### Start the Server - Bash Source: https://actorcore.org/llms-full.txt Commands to start the development server using different package managers after setting up the ActorCore application. ```Bash npm run dev ``` ```Bash yarn dev ``` ```Bash pnpm dev ``` ```Bash bun dev ``` -------------------------------- ### Start Development Server Source: https://actorcore.org/llms-full.txt Commands to start the development server configured with the File System driver using different package managers, assuming a 'dev' script is configured in package.json. ```bash npm run dev ``` ```bash yarn dev ``` ```bash pnpm dev ``` ```bash bun dev ``` -------------------------------- ### Quickstart: Defining and Using a User Actor with Resend Source: https://actorcore.org/llms-full.txt Define an ActorCore actor that stores a user's email and includes an action to send an email using the Resend SDK. The client code demonstrates how to get the actor instance and call its actions. ```typescript import { actor, setup } from "actor-core"; import { Resend } from "resend"; const resend = new Resend(process.env.RESEND_API_KEY); const user = actor({ state: { email: null as string | null, }, actions: { // Example: Somehow acquire the user's email register: async (c, email: string) => { c.state.email = email; }, // Example: Send an email sendExampleEmail: async (c) => { if (!c.state.email) throw new Error("No email registered"); await resend.emails.send({ from: "updates@yourdomain.com", to: c.state.email, subject: "Hello, world!", html: "

Lorem ipsum

", }); }, }, }); export const app = setup({ actors: { user } }); export type App = typeof app; ``` ```typescript import { createClient } from "actor-core"; import { App } from "./actors/app.ts"; const client = createClient("http://localhost:8787"); const userActor = await client.user.get({ tags: { user: "user123" } }); await userActor.register("user@example.com"); await userActor.sendExampleEmail(); ``` -------------------------------- ### Installing Resend SDK Source: https://actorcore.org/llms-full.txt Install the Resend Node.js SDK using npm to interact with the Resend API from your project. ```bash npm install resend ``` -------------------------------- ### Install ActorCore Packages (Shell) Source: https://actorcore.org/llms-full.txt Navigate into the newly created project directory and install the necessary `actor-core` and `@actor-core/react` packages using the chosen package manager. ```sh npm cd my-app npm install actor-core @actor-core/react ``` ```sh pnpm cd my-app pnpm add actor-core @actor-core/react ``` ```sh yarn cd my-app yarn add actor-core @actor-core/react ``` ```sh bun cd my-app bun add actor-core @actor-core/react ``` -------------------------------- ### Understand ActorCore Architecture (Windsurf Prompt) Source: https://actorcore.org/llms-full.txt Example prompts for Windsurf to get explanations about ActorCore's design, communication patterns, and lifecycle hooks. ```Shell # Get an overview of ActorCore's architecture Explain the architecture of ActorCore and how the different topologies work # Understand how actors communicate Explain how actors communicate with each other in the coordinate topology # Learn about specific concepts Explain the lifecycle hooks for actors and when each one is called ``` -------------------------------- ### Setup Vitest for ActorCore Testing - Bash Source: https://actorcore.org/llms-full.txt Provides the necessary bash commands to install Vitest as a development dependency and execute tests for an ActorCore project. ```bash # Install Vitest npm install -D vitest # Run tests npm test ``` -------------------------------- ### Start React Development Server (Shell) Source: https://actorcore.org/llms-full.txt Navigate back into the project directory and start the React development server using the standard `run dev` script, providing options for different package managers (npm, pnpm, yarn, bun). ```sh npm cd my-app npm run dev ``` ```sh pnpm cd my-app pnpm run dev ``` ```sh yarn cd my-app yarn dev ``` ```sh bun cd my-app bun run dev ``` -------------------------------- ### Starting the Development Server (Bash) Source: https://actorcore.org/llms-full.txt Commands to start the development server configured in the previous step using different package managers (npm, yarn, pnpm, bun). This typically runs a script defined in the project's package.json. ```bash npm run dev ``` ```bash yarn dev ``` ```bash pnpm dev ``` ```bash bun dev ``` -------------------------------- ### Start ActorCore Development Server (Shell) Source: https://actorcore.org/llms-full.txt Use the ActorCore CLI to launch the development server for the defined actors, providing options for different package managers (npm, pnpm, yarn, bun). This starts the backend and opens the studio. ```sh npm npx @actor-core/cli@latest dev actors/app.ts ``` ```sh pnpm pnpm exec @actor-core/cli@latest dev actors/app.ts ``` ```sh yarn yarn @actor-core/cli@latest dev actors/app.ts ``` ```sh bun bunx @actor-core/cli@latest dev actors/app.ts ``` -------------------------------- ### Install File System Driver Packages Source: https://actorcore.org/llms-full.txt Install the necessary npm packages for the File System driver and the Node.js platform adapter using various package managers. ```bash npm install @actor-core/file-system @actor-core/nodejs ``` ```bash yarn add @actor-core/file-system @actor-core/nodejs ``` ```bash pnpm add @actor-core/file-system @actor-core/nodejs ``` ```bash bun add @actor-core/file-system @actor-core/nodejs ``` -------------------------------- ### Create Server with File System Driver Source: https://actorcore.org/llms-full.txt Example TypeScript code demonstrating how to set up a simple server using the File System driver and the Node.js platform adapter. It initializes the driver with a FileSystemGlobalState instance. ```typescript import { serve } from "@actor-core/nodejs"; import { FileSystemManagerDriver, FileSystemActorDriver, FileSystemGlobalState } from "@actor-core/file-system"; const fsState = new FileSystemGlobalState(); serve(app, { topology: "standalone", drivers: { manager: new FileSystemManagerDriver(app, fsState), actor: new FileSystemActorDriver(fsState) } }); ``` -------------------------------- ### Handling Actor Start with onStart Hook (TypeScript) Source: https://actorcore.org/llms-full.txt The `onStart` hook is invoked every time the actor starts, including initial startup, restarts, code upgrades, or after crashes. It executes after initialization but before accepting connections. This hook is suitable for setting up resources or starting background tasks like intervals. ```typescript import { actor } from "actor-core"; const counter = actor({ state: { count: 0 }, onStart: (c) => { console.log('Actor started with count:', c.state.count); // Set up interval for automatic counting const intervalId = setInterval(() => { c.state.count++; console.log('Auto-increment:', c.state.count); }, 10000); // Store interval ID to clean up later if needed c.custom.intervalId = intervalId; }, actions: { /* ... */ } }); ``` -------------------------------- ### Example Prompts for Understanding ActorCore Architecture Source: https://actorcore.org/llms-full.txt Provides example natural language prompts to ask an LLM (like Cursor) to understand the overall structure, communication patterns, and concepts within the ActorCore codebase. ```Prompt # Get an overview of ActorCore's architecture Explain the architecture of ActorCore and how the different topologies work # Understand how actors communicate Explain how actors communicate with each other in the coordinate topology # Learn about specific concepts Explain the lifecycle hooks for actors and when each one is called ``` -------------------------------- ### Setting up and Serving an Actor-Core Application Source: https://actorcore.org/llms-full.txt This TypeScript code demonstrates how to create an Actor-Core application using `setup`, including the `chatRoom` actor, and then serve it using the `serve` function. It also exports the application type for client usage. ```typescript import { setup, serve } from "actor-core"; import chatRoom from "./chat_room"; // Create the application const app = setup({ actors: { chatRoom } }); // Start serving on default port serve(app); // Export the app type for client usage export type App = typeof app; ``` -------------------------------- ### Install Bun Platform Package Source: https://actorcore.org/llms-full.txt Use the Bun package manager to add the required ActorCore platform package for Bun. This command fetches and installs the necessary dependency. ```sh bun add @actor-core/bun ``` -------------------------------- ### Start ActorCore Development Server Source: https://actorcore.org/llms-full.txt Launch the ActorCore development server using the command-line interface (`@actor-core/cli`) with different package managers (npm, pnpm, yarn, bun), specifying the actor definition file. ```sh npx @actor-core/cli@latest dev actors/app.ts ``` ```sh pnpm exec @actor-core/cli@latest dev actors/app.ts ``` ```sh yarn @actor-core/cli@latest dev actors/app.ts ``` ```sh bunx @actor-core/cli@latest dev actors/app.ts ``` -------------------------------- ### Install ActorCore Client Packages Source: https://actorcore.org/llms-full.txt Add the necessary `actor-core` package to the project using npm, pnpm, yarn, or bun. ```sh npm install actor-core ``` ```sh pnpm add actor-core ``` ```sh yarn add actor-core ``` ```sh bun add actor-core ``` -------------------------------- ### Example Prompts for Adding New Features to ActorCore Source: https://actorcore.org/llms-full.txt Provides example natural language prompts to ask an LLM (like Cursor) for assistance in creating new actors, adding authentication, or implementing error handling in ActorCore. ```Prompt # Create a new actor implementation Help me create a new actor for managing user sessions # Add authentication to an actor Show me how to add authentication to my actor's _onBeforeConnect method # Implement error handling Help me implement proper error handling for my actor's RPC methods ``` -------------------------------- ### Example Prompts for Finding ActorCore Code Source: https://actorcore.org/llms-full.txt Provides example natural language prompts to ask an LLM (like Cursor) to locate specific code implementations, patterns, or understand state management within the ActorCore codebase. ```Prompt # Find implementations of specific components Find the files that implement the Redis driver # Locate examples of specific patterns Show me examples of RPC methods in the codebase # Understand actor state management Explain how actor state is persisted between restarts ``` -------------------------------- ### Setting up Actor with Drizzle ORM and PostgreSQL in TypeScript Source: https://actorcore.org/llms-full.txt Shows how to integrate Drizzle ORM with an ActorCore actor for type-safe database operations using PostgreSQL. Includes schema definition, database connection setup, and example actions for getting and creating users with caching and broadcasting. ```typescript import { actor } from "actor-core"; import { drizzle } from "drizzle-orm/node-postgres"; import { pgTable, serial, text, timestamp } from "drizzle-orm/pg-core"; import { Pool } from "pg"; // Define your schema const users = pgTable("users", { id: serial("id").primaryKey(), name: text("name").notNull(), email: text("email").notNull().unique(), createdAt: timestamp("created_at").defaultNow() }); // Create a database connection const pool = new Pool({ connectionString: process.env.DATABASE_URL }); // Initialize Drizzle with the pool const db = drizzle(pool); // Create the actor const userActor = actor({ state: { // Actor state (frequently accessed data can be cached here) userCache: {} }, actions: { // Get a user by ID getUser: async (c, userId) => { // Check cache first if (c.state.userCache[userId]) { return c.state.userCache[userId]; } // Query the database const result = await db.select().from(users).where(eq(users.id, userId)); if (result.length === 0) { throw new Error(`User ${userId} not found`); } // Cache the result c.state.userCache[userId] = result[0]; return result[0]; }, // Create a new user createUser: async (c, userData) => { const result = await db.insert(users).values({ name: userData.name, email: userData.email }).returning(); // Broadcast the new user event c.broadcast("userCreated", result[0]); return result[0]; } } }); export default userActor; ``` -------------------------------- ### Starting ActorCore Development Server (Shell) Source: https://actorcore.org/llms-full.txt Commands to launch the ActorCore development server using the CLI for various package managers (npm, pnpm, yarn, bun). ```sh npx @actor-core/cli@latest dev actors/app.ts ``` ```sh pnpm exec @actor-core/cli@latest dev actors/app.ts ``` ```sh yarn @actor-core/cli@latest dev actors/app.ts ``` ```sh bunx @actor-core/cli@latest dev actors/app.ts ``` -------------------------------- ### Configuring CORS for Actor Service (TypeScript) Source: https://actorcore.org/llms-full.txt Provides an example of configuring Cross-Origin Resource Sharing (CORS) for an Actor service using the `setup` function. It shows how to specify the allowed origin for frontend applications. ```typescript import { setup } from "actor-core"; import counter from "./counter"; const app = setup({ actors: { counter }, // Change this to match your frontend's origin cors: { origin: "https://yourdomain.com" } }); ``` -------------------------------- ### Actor-Core Client Setup (Client) Source: https://actorcore.org/llms-full.txt Initializes the client-side connection to the Actor-Core server and sets up the React-specific hooks for interacting with actors. ```typescript import { createClient } from "actor-core/client"; import { createReactActorCore } from "@actor-core/react"; import { useState, useEffect } from "react"; import type { App } from "../actors/app"; import type { Message } from "./actor"; const client = createClient("http://localhost:6420"); ``` -------------------------------- ### Install Required Packages - Bash Source: https://actorcore.org/llms-full.txt Installs the necessary packages for using the ActorCore Redis driver and the Node.js platform driver, including ioredis for the Redis connection, using different package managers. ```Bash npm install @actor-core/redis @actor-core/nodejs ioredis ``` ```Bash yarn add @actor-core/redis @actor-core/nodejs ioredis ``` ```Bash pnpm add @actor-core/redis @actor-core/nodejs ioredis ``` ```Bash bun add @actor-core/redis @actor-core/nodejs ioredis ``` -------------------------------- ### Example Prompts for Debugging ActorCore Issues Source: https://actorcore.org/llms-full.txt Provides example natural language prompts to ask an LLM (like Cursor) for help in diagnosing and fixing common issues like connection problems, state persistence failures, or performance bottlenecks in ActorCore. ```Prompt # Diagnose connection problems My actor connections are dropping, help me debug why # Fix state persistence issues My actor state isn't persisting between restarts, what could be wrong? # Address scaling problems My actors are using too much memory, how can I optimize them? ``` -------------------------------- ### Calling Action to Trigger Broadcast (Client - TypeScript) Source: https://actorcore.org/llms-full.txt Shows a client-side example using `actor-core/client` to connect to an actor service, get an actor instance, and call an action (`sendMessage`) that triggers an event broadcast. ```typescript import { createClient } from "actor-core/client"; import type { App } from "./src/index"; const client = createClient("http://localhost:6420"); const chatRoom = await client.chatRoom.get(); await chatRoom.sendMessage('Hello, world!'); ``` -------------------------------- ### Installing ActorCore Node.js Dependency Source: https://actorcore.org/llms-full.txt Install the ActorCore Node.js package using various package managers like npm, pnpm, yarn, or bun. ```sh npm install @actor-core/nodejs ``` ```sh pnpm add @actor-core/nodejs ``` ```sh yarn add @actor-core/nodejs ``` ```sh bun add @actor-core/nodejs ``` -------------------------------- ### Defining ActorCore Node.js Server Source: https://actorcore.org/llms-full.txt Create the main server file, import necessary modules, and start the server using the default file-system driver. ```typescript import { serve } from "@actor-core/nodejs"; import { app } from "../actors/app"; // Start the server with file-system driver (default) serve(app); ``` -------------------------------- ### Define ActorCore Server Entry Point (Bun) Source: https://actorcore.org/llms-full.txt Create the main server file (e.g., src/index.ts) that imports the Bun-specific serve function and starts the ActorCore server with your application logic. It defaults to using the file-system driver. ```typescript import { serve } from "@actor-core/bun"; import { app } from "../actors/app"; // Start the server with file-system driver (default) serve(app); ``` -------------------------------- ### Installing ActorCore Memory and Node.js Packages (Bash) Source: https://actorcore.org/llms-full.txt Install the necessary npm, yarn, pnpm, or bun packages for using the ActorCore Memory and Node.js drivers. These packages provide the core functionality for running actors with in-memory state and a Node.js runtime. ```bash npm install @actor-core/memory @actor-core/nodejs ``` ```bash yarn add @actor-core/memory @actor-core/nodejs ``` ```bash pnpm add @actor-core/memory @actor-core/nodejs ``` ```bash bun add @actor-core/memory @actor-core/nodejs ``` -------------------------------- ### Creating ActorCore Client in TypeScript Source: https://actorcore.org/llms-full.txt Provides an example of how to create a client application that connects to an ActorCore service using the 'createClient' function from 'actor-core/client' in TypeScript. ```typescript import { createClient } from "actor-core/client"; import type { App } from "../src/index"; // Create a client with the connection address and app type const client = createClient(/* CONNECTION ADDRESS */); ``` -------------------------------- ### Example: Simple Counter using React Hooks (TSX) Source: https://actorcore.org/llms-full.txt This comprehensive example demonstrates how to use `createClient`, `createReactActorCore`, `useActor`, and `useActorEvent` together to build a simple counter component that interacts with an ActorCore actor. It shows connecting to the actor, subscribing to a 'newCount' event, and calling an 'increment' action. ```tsx import { createClient } from "actor-core/client"; import { createReactActorCore } from "@actor-core/react"; import type { App } from "../actors/app"; import { useState } from "react"; // Connect to ActorCore const client = createClient("http://localhost:6420"); const { useActor, useActorEvent } = createReactActorCore(client); function Counter() { // Get actor and track count const [{ actor }] = useActor("counter"); const [count, setCount] = useState(0); // Listen for count updates useActorEvent({ actor, event: "newCount" }, setCount); return (

Count: {count}

); } ``` -------------------------------- ### Find ActorCore Code (Windsurf Prompt) Source: https://actorcore.org/llms-full.txt Example prompts for Windsurf to locate specific code implementations, patterns, or understand state management within an ActorCore project. ```Shell # Find implementations of specific components Find the files that implement the Redis driver # Locate examples of specific patterns Show me examples of RPC methods in the codebase # Understand actor state management Explain how actor state is persisted between restarts ``` -------------------------------- ### Setting up ActorCore Server with Hono on Bun Source: https://actorcore.org/llms-full.txt Demonstrates integrating ActorCore with a Hono application for the Bun runtime, including app setup, router creation, mounting the router, and passing the WebSocket handler to Bun's server configuration. Requires specifying a `basePath`. ```typescript import { Hono } from "hono"; import { setup, createRouter } from "@actor-core/bun"; import counter from "./counter"; // Create your Hono app const honoApp = new Hono(); // Add your custom routes honoApp.get("/", (c) => c.text("Welcome to my app!")); honoApp.get("/hello", (c) => c.text("Hello, world!")); // Setup the ActorCore app const app = setup({ actors: { counter }, // IMPORTANT: Must specify the same basePath where your router is mounted basePath: "/my-path" }); // Create a router from the app const { router: actorRouter, webSocketHandler } = createRouter(app); // Mount the ActorCore router at /my-path honoApp.route("/my-path", actorRouter); // Export the app type for client usage export type App = typeof app; // Create and start the server export default { port: 6420, fetch: honoApp.fetch, // IMPORTANT: Pass the webSocketHandler to Bun websocket: webSocketHandler, }; ``` -------------------------------- ### ActorCore Development Guide Prompt Content Source: https://actorcore.org/llms-full.txt Contains the Markdown content of the `prompt.txt` file, intended to be provided to LLMs as context about ActorCore naming conventions and terminology. ```Markdown # ActorCore Development Guide This guide contains essential information for working with the ActorCore project. ## Project Naming and Terminology - Use `ActorCore` when referring to the project in documentation and plain English - Use `actor-core` (kebab-case) when referring to the project in code, package names, and imports ``` -------------------------------- ### Setting up Actor with PostgreSQL (pg) in TypeScript Source: https://actorcore.org/llms-full.txt Demonstrates creating an ActorCore actor that connects to a PostgreSQL database using the 'pg' library, including connection pooling, actor lifecycle hooks (onStart, onShutdown), and example actions for fetching and inserting data. ```typescript import { actor } from "actor-core"; import { Pool } from "pg"; // Create a database connection pool const pool = new Pool({ user: "your_db_user", host: "localhost", database: "your_db_name", password: "your_db_password", port: 5432, }); // Create the actor const databaseActor = actor({ state: { // Local state if needed lastQueryTime: 0 }, // Initialize any resources onStart: (c) => { console.log("Database actor started"); }, // Clean up resources if needed onShutdown: async (c) => { await pool.end(); console.log("Database connections closed"); }, // Define actions actions: { // Example action to fetch data from database fetchData: async (c) => { try { const result = await pool.query("SELECT * FROM your_table"); c.state.lastQueryTime = Date.now(); return result.rows; } catch (error) { console.error("Error fetching data:", error); throw new Error("Failed to fetch data"); } }, // Example action to insert data into database insertData: async (c, data) => { try { await pool.query( "INSERT INTO your_table (column1, column2) VALUES ($1, $2)", [data.value1, data.value2] ); c.state.lastQueryTime = Date.now(); return { success: true }; } catch (error) { console.error("Error inserting data:", error); throw new Error("Failed to insert data"); } } } }); export default databaseActor; ``` -------------------------------- ### Configuring Client Options - TypeScript Source: https://actorcore.org/llms-full.txt Provides an example of configuring the ActorCore client during initialization using the `createClient` function. Options include specifying the data `encoding` ('cbor' or 'json') and a prioritized list of `supportedTransports` ('websocket', 'sse'). ```TypeScript // Example with all client options const client = createClient( "https://actors.example.com", { // Data serialization format encoding: "cbor", // or "json" // Network transports in order of preference supportedTransports: ["websocket", "sse"] } ); ``` -------------------------------- ### Setting up ActorCore Server with Hono on Node.js Source: https://actorcore.org/llms-full.txt Illustrates integrating ActorCore with a Hono application running on Node.js, covering app setup, router creation, mounting the router, and injecting the WebSocket handler into the Node.js server. Requires specifying a `basePath`. ```typescript import { serve } from "@hono/node-server"; import { Hono } from "hono"; import { setup, createRouter } from "@actor-core/nodejs"; import counter from "./counter"; // Create your Hono app const honoApp = new Hono(); // Add your custom routes honoApp.get("/", (c) => c.text("Welcome to my app!")); honoApp.get("/hello", (c) => c.text("Hello, world!")); // Setup the ActorCore app const app = setup({ actors: { counter }, // IMPORTANT: Must specify the same basePath where your router is mounted basePath: "/my-path" }); // Create a router from the app const { router: actorRouter, injectWebSocket } = createRouter(app); // Mount the ActorCore router at /my-path honoApp.route("/my-path", actorRouter); // Export the app type for client usage export type App = typeof app; // Create server with the combined app const server = serve({ fetch: honoApp.fetch, port: 6420, }); // IMPORTANT: Inject the websocket handler into the server injectWebSocket(server); console.log("Server running at http://localhost:6420"); ``` -------------------------------- ### Add ActorCore Features (Windsurf Prompt) Source: https://actorcore.org/llms-full.txt Example prompts for Windsurf to assist in creating new actors, adding authentication, or implementing error handling in an ActorCore application. ```Shell # Create a new actor implementation Help me create a new actor for managing user sessions # Add authentication to an actor Show me how to add authentication to my actor's _onBeforeConnect method # Implement error handling Help me implement proper error handling for my actor's RPC methods ``` -------------------------------- ### Debug ActorCore Issues (Windsurf Prompt) Source: https://actorcore.org/llms-full.txt Example prompts for Windsurf to help diagnose and resolve common issues in ActorCore applications, such as connection problems, state persistence failures, or performance bottlenecks. ```Shell # Diagnose connection problems My actor connections are dropping, help me debug why # Fix state persistence issues My actor state isn't persisting between restarts, what could be wrong? # Address scaling problems My actors are using too much memory, how can I optimize them? ``` -------------------------------- ### Connecting to Actor using Tags (Find or Create) Source: https://actorcore.org/llms-full.txt Use the `get()` method to find an existing actor matching the provided tags or create a new one if none is found. This is the most common connection method. ```TypeScript // Connect to a chat room for the "general" channel const room = await client.chatRoom.get({ name: "chat_room", channel: "general" }); // Now you can call methods on the actor await room.sendMessage("Alice", "Hello everyone!"); ``` ```Rust use actor_core_client::GetOptions; use serde_json::json; // Connect to a chat room for the "general" channel let tags = vec![ ("name".to_string(), "chat_room".to_string()), ("channel".to_string(), "general".to_string()), ]; let mut options = GetOptions { tags: Some(tags), ..Default::default() }; let room = client.get("chatRoom", options) .await .expect("Failed to connect to chat room"); // Now you can call methods on the actor room.action("sendMessage", vec![json!("Alice"), json!("Hello everyone!")]) .await .expect("Failed to send message"); ``` -------------------------------- ### Understand ActorCore Codebase with Claude Code (Bash) Source: https://actorcore.org/llms-full.txt Use these bash commands with the `claude` CLI to get high-level explanations and architectural insights into your ActorCore project. Requires the Claude Code CLI and a properly configured CLAUDE.md file. ```bash claude "explain the architecture of ActorCore and how the different topologies work" ``` ```bash claude "explain how actors communicate with each other in the coordinate topology" ``` ```bash claude "explain the lifecycle hooks for actors and when each one is called" ``` -------------------------------- ### Interacting with an ActorCore Monitor Actor Client (TypeScript) Source: https://actorcore.org/llms-full.txt Demonstrates how a client application can connect to an ActorCore application, get a specific actor instance (`monitor` with ID `api-service`), and call an action on it (`configure`) to set the alert email address. Requires `createClient` from ActorCore. ```typescript const client = createClient({ url: "http://localhost:3000" }); const systemMonitor = await client.monitor.get({ id: "api-service" }); await systemMonitor.configure("admin@example.com"); ``` -------------------------------- ### Defining a Full Actor with Lifecycle Hooks and Actions (TypeScript) Source: https://actorcore.org/llms-full.txt This snippet demonstrates a complete actor definition using `actor-core`, including state initialization, creation logic, dynamic connection state based on parameters, various lifecycle hooks (start, state change, connect/disconnect), and defined actions (`increment`, `reset`) with authorization checks. ```typescript import { actor } from "actor-core"; const counter = actor({ // Initialize state createState: () => ({ count: 0 }), // Initialize actor (run setup that doesn't affect initial state) onCreate: (c) => { console.log('Counter actor initialized'); // Set up external resources, etc. }, // Define default connection state connState: { role: "guest" }, // Dynamically create connection state based on params createConnState: (c, { params }) => { // Get auth info from validation const authToken = params.authToken; const authInfo = validateAuthToken(authToken); return { userId: authInfo?.userId || "anonymous", role: authInfo?.role || "guest" }; }, // Lifecycle hooks onStart: (c) => { console.log('Counter started with count:', c.state.count); }, onStateChange: (c, newState) => { c.broadcast('countUpdated', { count: newState.count }); }, onBeforeConnect: (c, { params }) => { // Validate auth token const authToken = params.authToken; if (!authToken) { throw new Error('Missing auth token'); } // Validate with your API and determine the user const authInfo = validateAuthToken(authToken); if (!authInfo) { throw new Error('Invalid auth token'); } // If validation succeeds, connection proceeds // Connection state will be set by createConnState }, onConnect: (c) => { console.log(`User ${c.conn.state.userId} connected`); }, onDisconnect: (c) => { console.log(`User ${c.conn.state.userId} disconnected`); }, // Define actions actions: { increment: (c) => { c.state.count++; return c.state.count; }, reset: (c) => { // Check if user has admin role if (c.conns.state.role !== "admin") { throw new Error("Unauthorized: requires admin role"); } c.state.count = 0; return c.state.count; } } }); export default counter; ``` -------------------------------- ### Basic Actor Testing with setupTest - TypeScript Source: https://actorcore.org/llms-full.txt Demonstrates how to write a basic test for an ActorCore actor using `setupTest` to create a test environment. It shows how to obtain an actor client, interact with actor actions, and make assertions on the actor's state. ```ts import { test, expect } from "vitest"; import { setupTest } from "actor-core/test"; import { app } from "../src/index"; test("my actor test", async (test) => { const { client } = await setupTest(test, app); // Now you can interact with your actor through the client const myActor = await client.myActor.get(); // Test your actor's functionality await myActor.someAction(); // Make assertions const result = await myActor.getState(); expect(result).toEqual("updated"); }); ``` ```ts import { actor, setup } from "actor-core"; const myActor = actor({ state: { value: "initial" }, actions: { someAction: (c) => { c.state.value = "updated"; return c.state.value; }, getState: (c) => { return c.state.value; } } }); export const app = setup({ actors: { myActor } }); export type App = typeof app; ``` -------------------------------- ### Calling Action to Trigger Specific Event Send (Client - TypeScript) Source: https://actorcore.org/llms-full.txt Shows a client-side example using `actor-core/client` to connect to an actor service, get an actor instance, and call an action (`sendPrivateMessage`) that triggers sending an event to a specific connection ID. ```typescript import { createClient } from "actor-core/client"; import type { App } from "./src/index"; const client = createClient("http://localhost:6420"); const chatRoom = await client.chatRoom.get(); await chatRoom.sendPrivateMessage(123, 'Hello, world!'); ``` -------------------------------- ### Handling Manual Synchronization with Actor Source: https://actorcore.org/llms-full.txt This asynchronous function triggers a manual synchronization. It first checks if the `actor` is available. It sets the sync status to 'Syncing...', pushes all current local contacts to the actor, then fetches all changes from the actor (starting from timestamp 0 to get everything), updates the local contacts state with the fetched changes, records the new timestamp, and finally sets the status to 'Synced' or 'Offline' based on success or failure. ```TypeScript // Manual sync const handleSync = async () => { if (!actor) return; setSyncStatus("Syncing..."); try { // Push all contacts await actor.pushChanges(contacts); // Get all changes const changes = await actor.getChanges(0); setContacts(changes.changes); lastSyncTime.current = changes.timestamp; setSyncStatus("Synced"); } catch (error) { setSyncStatus("Offline"); } }; ``` -------------------------------- ### Creating a New Rust Project (Shell) Source: https://actorcore.org/llms-full.txt Commands to initialize a new Rust project using Cargo and navigate into the project directory. ```sh cargo new my-app cd my-app ``` -------------------------------- ### Setting Up Client and Connecting to Actor (React/TypeScript) Source: https://actorcore.org/llms-full.txt Initializes the client-side connection to the actor server using `actor-core/client` and integrates it with React via `@actor-core/react`. It demonstrates connecting to a specific actor instance ("document") using the `useActor` hook, identifying the instance by a tag derived from the URL query parameters. Requires `actor-core/client` and `@actor-core/react`. ```typescript import { createClient } from "actor-core/client"; import { createReactActorCore } from "@actor-core/react"; import { useState, useEffect } from "react"; import type { App } from "../actors/app"; const client = createClient("http://localhost:6420"); const { useActor, useActorEvent } = createReactActorCore(client); export function DocumentEditor() { // Connect to actor for this document ID from URL const documentId = new URLSearchParams(window.location.search).get('id') || 'default-doc'; const [{ actor, connectionId }] = useActor("document", { tags: { id: documentId } }); // Local state ``` -------------------------------- ### Initializing a new Actor-Core Project Source: https://actorcore.org/llms-full.txt These commands use various package managers (npx, npm, pnpm, yarn, bun) to run the `create-actor` script, which sets up a new Actor-Core project directory. ```sh npx create-actor@latest ``` ```sh npm create actor@latest ``` ```sh pnpm create actor@latest ``` ```sh yarn create actor@latest ``` ```sh bun create actor@latest ``` -------------------------------- ### Installing Rivet Package Source: https://actorcore.org/llms-full.txt Install the ActorCore Rivet platform package using various package managers like npm, pnpm, yarn, or bun. This package is required to build and deploy ActorCore applications. ```sh npm install @actor-core/rivet ``` ```sh pnpm add @actor-core/rivet ``` ```sh yarn add @actor-core/rivet ``` ```sh bun add @actor-core/rivet ``` -------------------------------- ### Creating a Simple Server with Memory Driver (TypeScript) Source: https://actorcore.org/llms-full.txt Demonstrates how to set up a basic ActorCore server using the in-memory driver (MemoryManagerDriver, MemoryActorDriver) and the Node.js runtime (serve). This configuration is suitable for development and testing. ```typescript import { serve } from "@actor-core/nodejs" import { MemoryManagerDriver, MemoryActorDriver, MemoryGlobalState } from "@actor-core/memory"; const memoryState = new MemoryGlobalState(); serve(app, { topology: "standalone", drivers: { manager: new MemoryManagerDriver(app, memoryState), actor: new MemoryActorDriver(memoryState), }, }); ``` -------------------------------- ### Configuring ActorCore Node.js Driver Source: https://actorcore.org/llms-full.txt Specify a different driver mode, such as 'in-memory', when starting the ActorCore server instead of the default file-system driver. ```typescript serve(app, { mode: "in-memory", // Switch to in-memory (file-system is default) }); ``` -------------------------------- ### Build and Run Production Server (Bun) Source: https://actorcore.org/llms-full.txt Execute these shell commands to build your TypeScript source file into a production-ready JavaScript file using `bun build` and then run the compiled output using `bun`. ```sh bun build ./src/index.ts --outdir ./dist bun ./dist/index.js ``` -------------------------------- ### Create React Project with Vite (Shell) Source: https://actorcore.org/llms-full.txt Use Vite to initialize a new React project with TypeScript support, providing options for different package managers (npm, pnpm, yarn, bun). ```sh npm npm create vite@latest my-app -- --template react-ts ``` ```sh pnpm pnpm create vite@latest my-app --template react-ts ``` ```sh yarn yarn create vite my-app --template react-ts ``` ```sh bun bunx create-vite@latest my-app --template react-ts ``` -------------------------------- ### Update Client Endpoint Source: https://actorcore.org/llms-full.txt Modify your client-side code to connect to the newly deployed ActorCore server endpoint. Examples are provided for TypeScript and Rust clients. ```typescript const client = createClient(/* FILL ME IN */); ``` ```rust let client = Client::new(/* FILL ME IN */, TransportKind::WebSocket, EncodingKind::Cbor); ``` -------------------------------- ### Accessing Actor Name (c.name) in Actor-core Source: https://actorcore.org/llms-full.txt Provides a simple example of how to access the name of the currently running actor instance using `c.name` from the context object. ```typescript const actorName = c.name; ``` -------------------------------- ### Configure Redis Connection with Options - TypeScript Source: https://actorcore.org/llms-full.txt Demonstrates how to create an ioredis connection with custom configuration options (host, port, password) and then use this connection instance to initialize the ActorCore Redis drivers. ```TypeScript import Redis from "ioredis"; import { RedisManagerDriver } from "@actor-core/redis/manager"; import { RedisActorDriver } from "@actor-core/redis/actor"; import { RedisCoordinateDriver } from "@actor-core/redis/coordinate"; // Create a Redis connection const redis = new Redis({ host: "localhost", port: 6379, password: "foobar", }); // Create the Redis drivers const managerDriver = new RedisManagerDriver(redis); const actorDriver = new RedisActorDriver(redis); const coordinateDriver = new RedisCoordinateDriver(redis); ``` -------------------------------- ### Configuring Client Options - Rust Source: https://actorcore.org/llms-full.txt Demonstrates how to create a Rust client instance using `Client::new`. Configuration options like the endpoint URL, preferred `TransportKind` ('WebSocket', 'Sse'), and `EncodingKind` ('Cbor', 'Json') are passed as arguments. Note that the Rust client currently supports only a single transport type. ```Rust use actor_core_client::{Client, TransportKind, EncodingKind}; // Create client with specific options let client = Client::new( "https://actors.example.com".to_string(), TransportKind::WebSocket, // or TransportKind::Sse EncodingKind::Cbor, // or EncodingKind::Json ); // Rust does not support accepting multiple transports ``` -------------------------------- ### Updating Client Endpoint Source: https://actorcore.org/llms-full.txt Update your client code to connect to the newly deployed ActorCore application by providing the endpoint URL. Examples are shown for TypeScript and Rust clients. ```typescript const client = createClient(/* FILL ME IN */); ``` ```rust let client = Client::new(/* FILL ME IN */, TransportKind::WebSocket, EncodingKind::Cbor); ``` -------------------------------- ### Creating ActorCore Client in Rust Source: https://actorcore.org/llms-full.txt Demonstrates how to create a client application that connects to an ActorCore service using the 'Client::new' constructor from 'actor_core_client' in Rust, specifying connection address, transport, and encoding. ```rust use actor_core_client::{Client, TransportKind, EncodingKind}; // Create a client with connection address and configuration let client = Client::new( "http://localhost:6420".to_string(), // Connection address TransportKind::WebSocket, // Transport (WebSocket or SSE) EncodingKind::Cbor, // Encoding (Json or Cbor) ); ``` -------------------------------- ### Building ActorCore with Yarn Source: https://actorcore.org/llms-full.txt Initiates a production build for the entire ActorCore project using the configured build tool, typically Turbopack. ```Shell yarn build ``` -------------------------------- ### Accessing Authenticated Connection State in Actor Actions Source: https://actorcore.org/llms-full.txt Demonstrates how to access the connection state (c.conn.state) within an actor action after it has been set by createConnState. It shows an example of checking a role property for access control. ```typescript import { actor } from "actor-core"; const authenticatedActor = actor({ state: { // Actor state... }, createConnState: (c) => { // Authentication logic... return { userId: "user_123", role: "admin" }; }, actions: { exampleAdminCommand: (c) => { // Example of validating admin access if (c.conn.state.role !== 'admin') { throw new Error('User must be an admin'); } // Admin-only functionality... return { success: true }; } } }); ``` -------------------------------- ### Actor-Core Server Game Logic with Drizzle and SQLite Persistence Source: https://actorcore.org/llms-full.txt Defines the server-side `actor` for the game, integrating Drizzle ORM for SQLite database persistence of game settings and player data. The `onStart` hook initializes the actor's state by loading data from the database. An internal `setInterval` loop processes player inputs, updates player positions, and prepares the game state for broadcasting to clients. ```typescript import { actor } from "actor-core"; import { drizzle } from "@actor-core/drizzle"; import { players, gameSettings } from "./schema"; export type Position = { x: number; y: number }; export type Input = { x: number; y: number }; export type Player = { id: string; position: Position; input: Input }; const gameRoom = actor({ sql: drizzle(), // Store game settings and player inputs in memory for performance createVars: () => ({ playerCache: {} as Record, mapSize: 800 }), onStart: async (c) => { // Get or initialize game settings const settings = await c.db .select() .from(gameSettings) .get(); if (settings) { c.vars.mapSize = settings.mapSize; } else { await c.db .insert(gameSettings) .values({ mapSize: c.vars.mapSize }); } // Load existing players into memory const existingPlayers = await c.db .select() .from(players); for (const player of existingPlayers) { c.vars.playerCache[player.id] = { id: player.id, position: { x: player.positionX, y: player.positionY }, input: { x: player.inputX, y: player.inputY } }; } // Set up game update loop setInterval(async () => { const worldUpdate = { playerList: [] }; let changed = false; for (const id in c.vars.playerCache) { const player = c.vars.playerCache[id]; const speed = 5; // Update position based on input player.position.x += player.input.x * speed; player.position.y += player.input.y * speed; // Keep player in bounds player.position.x = Math.max(0, Math.min(player.position.x, c.vars.mapSize)); player.position.y = Math.max(0, Math.min(player.position.y, c.vars.mapSize)); // Add to list for broadcast worldUpdate.playerList.push(player); changed = true; } // Save player positions to database if changed if (changed) { ``` -------------------------------- ### Running the Rust Client (Shell) Source: https://actorcore.org/llms-full.txt Command to compile and execute the Rust client application using Cargo. ```sh cargo run ``` -------------------------------- ### Modifying Actor State in Actions in Actor-Core Typescript Source: https://actorcore.org/llms-full.txt Provides examples of how to update an actor's persistent state by directly modifying properties on the `c.state` object within actor actions. Changes to `c.state` are automatically persisted. ```typescript import { actor } from "actor-core"; const counter = actor({ state: { count: 0 }, actions: { // Define action to update state increment: (c) => { // Update state, this will automatically be persisted c.state.count += 1; return c.state.count; }, add: (c, value) => { c.state.count += value; return c.state.count; } } }); ``` -------------------------------- ### Create Node.js Project with ActorCore Source: https://actorcore.org/llms-full.txt Initialize a new Node.js project with TypeScript support using different package managers (npm, pnpm, yarn, bun) and configure it for ES modules. ```sh mkdir my-app cd my-app npm init -y npm pkg set type=module ``` ```sh mkdir my-app cd my-app pnpm init pnpm pkg set type=module ``` ```sh mkdir my-app cd my-app yarn init -y yarn pkg set type=module ``` ```sh mkdir my-app cd my-app bun init -y ``` -------------------------------- ### Updating Actor State within an Action Source: https://actorcore.org/llms-full.txt This example shows how to modify an actor's state within an action function. The context object `c` provides access to the current state via `c.state`, which can be directly updated. ```typescript import { actor } from "actor-core"; const counter = actor({ state: { count: 0 }, actions: { // Example of state update in an action increment: (c) => { c.state.count += 1; return c.state.count; } } }); ``` -------------------------------- ### Configuring Deployment Topology (TypeScript) Source: https://actorcore.org/llms-full.txt Shows how to configure the deployment topology for an ActorCore application by setting the `topology` property in the configuration object. ```typescript const config = { topology: "standalone" // or "partition" or "coordinate" }; ``` -------------------------------- ### Adding Rust Dependencies (Shell) Source: https://actorcore.org/llms-full.txt Commands to add necessary crates for the ActorCore client, JSON serialization/deserialization, and asynchronous runtime using Cargo. ```sh cargo add actor-core-client cargo add serde_json cargo add tokio --features full ``` -------------------------------- ### Explicitly Disconnecting Actor/Client in TypeScript Source: https://actorcore.org/llms-full.txt Provides TypeScript code examples for explicitly disconnecting from a single actor instance using `actor.dispose()` and disconnecting the entire client connection using `client.dispose()`. Client connections are automatically cleaned up when they go out of scope. ```typescript // Disconnect from the actor await actor.dispose(); // Disconnect the entire client await client.dispose(); ``` -------------------------------- ### Creating React Client for Actor (TypeScript) Source: https://actorcore.org/llms-full.txt Sets up a React client using `@actor-core/react` to interact with the server-side actor. Demonstrates connecting to the actor with parameters, fetching initial data using `useEffect`, and implementing actions like adding and deleting notes. Uses `useActorEvent` to listen for real-time updates. ```typescript import { createClient } from "actor-core/client"; import { createReactActorCore } from "@actor-core/react"; import { useState, useEffect } from "react"; const client = createClient("http://localhost:6420"); const { useActor, useActorEvent } = createReactActorCore(client); export function NotesApp({ userId }: { userId: string }) { const [notes, setNotes] = useState>([]); const [newNote, setNewNote] = useState(""); // Connect to actor with auth token const [{ actor }] = useActor("notes", { params: { userId, token: "demo-token" } }); // Load initial notes useEffect(() => { if (actor) { actor.getNotes().then(setNotes); } }, [actor]); // Add a new note const addNote = async () => { if (actor && newNote.trim()) { await actor.updateNote({ id: `note-${Date.now()}`, content: newNote }); setNewNote(""); } }; // Delete a note const deleteNote = (id: string) => { if (actor) { actor.deleteNote({ id }); } }; // Listen for realtime updates useActorEvent({ actor, event: "noteAdded" }, (note) => { setNotes(notes => [...notes, note]); ``` -------------------------------- ### Explicitly Disconnecting Actor/Client in Rust Source: https://actorcore.org/llms-full.txt Provides Rust code examples for explicitly disconnecting from a single actor instance using `actor.disconnect().await`. It also shows how the client is automatically cleaned up when it goes out of scope or can be explicitly dropped using `drop(client)`. ```rust // Disconnect from the actor actor.disconnect().await; // The client will be cleaned up automatically when it goes out of scope // Or explicitly drop it with: drop(client); ``` -------------------------------- ### Setting up ActorCore Server with Hono on Cloudflare Workers Source: https://actorcore.org/llms-full.txt Demonstrates how to integrate ActorCore with a Hono application for Cloudflare Workers, including setting up the ActorCore app, creating and mounting the router, and exporting the necessary handlers. Requires specifying a `basePath`. ```typescript import { createRouter } from "@actor-core/cloudflare-workers"; import { setup } from "actor-core"; import { Hono } from "hono"; import counter from "./counter"; // Create your Hono app inside the fetch handler const honoApp = new Hono(); // Add your custom routes honoApp.get("/", (c) => c.text("Welcome to my app!")); honoApp.get("/hello", (c) => c.text("Hello, world!")); // Setup the ActorCore app const app = setup({ 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: actorRouter, ActorHandler } = createRouter(app); // Mount the ActorCore router at /my-path honoApp.route("/my-path", actorRouter); // Export the app type for client usage export type App = typeof app; // IMPORTANT: Must export `ActorHandler` as this exact name export { honoApp as default, ActorHandler }; ```