[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-rivet-rivetkit-client-rust":3,"mdc--aeovse-key":34,"related-org-rivet-rivetkit-client-rust":2952,"related-repo-rivet-rivetkit-client-rust":3150},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":23,"repoUrl":24,"updatedAt":25,"license":26,"forks":27,"topics":28,"repo":29,"sourceUrl":32,"mdContent":33},"rivetkit-client-rust","build RivetKit Rust clients","RivetKit Rust client guidance. Use for Rust clients and backends that connect to Rivet Actors with rivetkit::client, create typed actor handles, call actions, or manage connections.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"rivet","Rivet","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Frivet.png","rivet-dev",[13,17,20],{"name":14,"slug":15,"type":16},"Backend","backend","tag",{"name":18,"slug":19,"type":16},"Rust","rust",{"name":21,"slug":22,"type":16},"API Development","api-development",17,"https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Fskills","2026-07-24T05:39:02.105888",null,7,[],{"repoUrl":24,"stars":23,"forks":27,"topics":30,"description":31},[],"Generated skill files for Rivet AI integrations","https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Fskills\u002Ftree\u002FHEAD\u002Frivetkit-client-rust","---\nname: \"rivetkit-client-rust\"\ndescription: \"RivetKit Rust client guidance. Use for Rust clients and backends that connect to Rivet Actors with rivetkit::client, create typed actor handles, call actions, or manage connections.\"\n---\n\n# RivetKit Rust Client\n\nUse this skill when building Rust clients that connect to Rivet Actors with `rivetkit::client`.\n\n## Version\n\nRivetKit version: 2.3.7\n\n## First Steps\n\n1. Add the dependency\n   ```sh\n   cargo add rivetkit anyhow async-trait\n   cargo add serde --features derive\n   cargo add tokio --features full\n   ```\n2. Create a client with `Client::new(ClientConfig::new(endpoint))` and call typed actions with `get_or_create_typed_default::\u003CA>(...)`.\n\n## Error Handling Policy\n\n- Prefer fail-fast behavior by default. Propagate `anyhow::Result` with `?`.\n- Avoid swallowing errors with broad `match` arms unless absolutely needed.\n- If an error is handled inline, handle it explicitly, at minimum by logging it.\n\nRust support is in beta. The supported public Rust API is `rivetkit` and `rivetkit::client`; lower-level crates are internal implementation details and do not carry a stability guarantee. See the full API reference on [docs.rs\u002Frivetkit](https:\u002F\u002Fdocs.rs\u002Frivetkit), or the runnable [`hello-world-rust`](https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fhello-world-rust) example.\n\n## Getting Started\n\nSee the [Rust quickstart guide](\u002Fdocs\u002Factors\u002Fquickstart\u002Frust) for getting started.\n\n## Install\n\nAdd the `rivetkit` crate and its companions:\n\n```sh\ncargo add rivetkit anyhow async-trait\ncargo add serde --features derive\ncargo add tokio --features full\n```\n\nThe Rust client is strongly typed. It shares the same action and event types as your actor, so define your actor in `src\u002Flib.rs` and import those types from both your server and your client. There is no need to redefine the actor on the client. See [Define Your Actor](\u002Fdocs\u002Factors\u002Fquickstart\u002Frust#define-your-actor) in the quickstart for the actor definition this page builds on.\n\n## Minimal Client\n\n```rust @nocheck\nuse counter::{Counter, Increment};\nuse rivetkit::{\n\tclient::{Client, ClientConfig},\n\tprelude::*,\n\tTypedClientExt,\n};\n\n#[tokio::main]\nasync fn main() -> Result\u003C()> {\n\tlet client = Client::new(ClientConfig::new(\"http:\u002F\u002Flocalhost:6420\").namespace(\"default\"));\n\n\tlet counter = client.get_or_create_typed_default::\u003CCounter>(\"counter\", [\"my-counter\"])?;\n\tlet count = counter.send(Increment { amount: 1 }).await?;\n\tprintln!(\"New count: {count}\");\n\n\tOk(())\n}\n```\n\n`counter` here is your crate name (the package `name` in `Cargo.toml`, with dashes as underscores). `Counter` and `Increment` are the types you defined alongside your actor.\n\n## Stateless vs Stateful\n\n```rust @nocheck\nuse counter::{Counter, Increment, NewCount};\nuse rivetkit::{\n\tclient::{Client, ClientConfig},\n\tprelude::*,\n\tTypedClientExt,\n};\n\n#[tokio::main]\nasync fn main() -> Result\u003C()> {\n\tlet client = Client::new(ClientConfig::new(\"http:\u002F\u002Flocalhost:6420\").namespace(\"default\"));\n\tlet counter = client.get_or_create_typed_default::\u003CCounter>(\"counter\", [\"my-counter\"])?;\n\n\t\u002F\u002F Stateless: each call is independent\n\tcounter.send(Increment { amount: 1 }).await?;\n\n\t\u002F\u002F Stateful: keep a connection open for realtime events\n\tlet connection = counter.connect();\n\tconnection\n\t\t.on::\u003CNewCount>(|event| println!(\"count: {}\", event.count))\n\t\t.await;\n\tconnection.send(Increment { amount: 1 }).await?;\n\n\tconnection.disconnect().await;\n\tOk(())\n}\n```\n\nA stateless call on the handle opens a short-lived request per action. A connection keeps a WebSocket open so you can receive events and reuse it across calls.\n\n## Getting Actors\n\n```rust @nocheck\nuse counter::Counter;\nuse rivetkit::{\n\tclient::{Client, ClientConfig, GetOrCreateOptions},\n\tprelude::*,\n\tTypedClientExt,\n};\nuse serde_json::json;\n\n#[tokio::main]\nasync fn main() -> Result\u003C()> {\n\tlet client = Client::new(ClientConfig::new(\"http:\u002F\u002Flocalhost:6420\").namespace(\"default\"));\n\n\t\u002F\u002F Get or create an actor\n\tlet room = client.get_or_create_typed_default::\u003CCounter>(\"counter\", [\"room-42\"])?;\n\n\t\u002F\u002F Get an existing actor handle (fails when used if the actor does not exist)\n\tlet existing = client.get_typed_default::\u003CCounter>(\"counter\", [\"room-42\"])?;\n\n\t\u002F\u002F Create a new actor with input\n\tlet created = client.get_or_create_typed::\u003CCounter>(\n\t\t\"counter\",\n\t\t[\"game-1\"],\n\t\tGetOrCreateOptions {\n\t\t\tcreate_with_input: Some(json!({ \"mode\": \"ranked\" })),\n\t\t\t..Default::default()\n\t\t},\n\t)?;\n\n\t\u002F\u002F Get an actor handle by ID\n\tlet by_id = client.get_for_id(\"counter\", \"actor-id\", Default::default())?;\n\n\t\u002F\u002F Resolve the actor ID\n\tlet resolved_id = room.inner().resolve().await?;\n\tprintln!(\"Resolved ID: {resolved_id}\");\n\n\tOk(())\n}\n```\n\n`get_typed_default` \u002F `get_or_create_typed_default` use default options. The non-default variants (`get_typed` \u002F `get_or_create_typed`) take `GetOptions` \u002F `GetOrCreateOptions` for connection parameters, input, and region.\n\n## Connection Parameters\n\nPass connection parameters through the handle options. They are delivered to the actor's `create_conn_state` callback:\n\n```rust @nocheck\nuse counter::Counter;\nuse rivetkit::{\n\tclient::{Client, ClientConfig, GetOrCreateOptions},\n\tprelude::*,\n\tTypedClientExt,\n};\nuse serde_json::json;\n\n#[tokio::main]\nasync fn main() -> Result\u003C()> {\n\tlet client = Client::new(ClientConfig::new(\"http:\u002F\u002Flocalhost:6420\").namespace(\"default\"));\n\n\tlet chat = client.get_or_create_typed::\u003CCounter>(\n\t\t\"counter\",\n\t\t[\"general\"],\n\t\tGetOrCreateOptions {\n\t\t\tparams: Some(json!({ \"authToken\": \"jwt-token-here\" })),\n\t\t\t..Default::default()\n\t\t},\n\t)?;\n\n\tlet connection = chat.connect();\n\tconnection.disconnect().await;\n\tOk(())\n}\n```\n\n## Subscribing to Events\n\n`on` registers a typed callback for an event and returns once the subscription is registered:\n\n```rust @nocheck\nuse counter::{Counter, NewCount};\nuse rivetkit::{\n\tclient::{Client, ClientConfig},\n\tprelude::*,\n\tTypedClientExt,\n};\n\n#[tokio::main]\nasync fn main() -> Result\u003C()> {\n\tlet client = Client::new(ClientConfig::new(\"http:\u002F\u002Flocalhost:6420\").namespace(\"default\"));\n\tlet connection = client\n\t\t.get_or_create_typed_default::\u003CCounter>(\"counter\", [\"general\"])?\n\t\t.connect();\n\n\tconnection\n\t\t.on::\u003CNewCount>(|event| println!(\"count changed: {}\", event.count))\n\t\t.await;\n\n\tOk(())\n}\n```\n\nEvent callbacks are synchronous and run for every matching event. The actor's emitted event type (here `NewCount`) is decoded into the typed value for you.\n\n## Connection Lifecycle\n\nThe lower-level connection exposes lifecycle callbacks and the current status. Reach it with `connection.inner()`:\n\n```rust @nocheck\nuse counter::Counter;\nuse rivetkit::{\n\tclient::{Client, ClientConfig},\n\tprelude::*,\n\tTypedClientExt,\n};\n\n#[tokio::main]\nasync fn main() -> Result\u003C()> {\n\tlet client = Client::new(ClientConfig::new(\"http:\u002F\u002Flocalhost:6420\").namespace(\"default\"));\n\tlet connection = client\n\t\t.get_or_create_typed_default::\u003CCounter>(\"counter\", [\"general\"])?\n\t\t.connect();\n\tlet inner = connection.inner().clone();\n\n\tinner.on_open(|| println!(\"connected\")).await;\n\tinner.on_close(|| println!(\"disconnected\")).await;\n\tinner.on_error(|message| eprintln!(\"error: {message}\")).await;\n\tinner\n\t\t.on_status_change(|status| println!(\"status: {status:?}\"))\n\t\t.await;\n\n\tprintln!(\"current status: {:?}\", inner.conn_status());\n\n\tconnection.disconnect().await;\n\tOk(())\n}\n```\n\n`ConnectionStatus` is one of `Idle`, `Connecting`, `Connected`, or `Disconnected`. Connections reconnect automatically with backoff until you call `disconnect`.\n\n## Low-Level HTTP & WebSocket\n\nFor actors that implement `on_request` or `on_websocket`, call them directly on the untyped handle (`handle.inner()`). `fetch` returns a `reqwest::Response`, and `web_socket` returns a `tokio_tungstenite` stream. This example also needs a few extra crates:\n\n```sh\ncargo add futures-util tokio-tungstenite\ncargo add reqwest --features json\n```\n\n```rust @nocheck\nuse counter::Counter;\nuse futures_util::{SinkExt, StreamExt};\nuse reqwest::{header::HeaderMap, Method};\nuse rivetkit::{\n\tclient::{Client, ClientConfig},\n\tprelude::*,\n\tTypedClientExt,\n};\nuse tokio_tungstenite::tungstenite::Message;\n\n#[tokio::main]\nasync fn main() -> Result\u003C()> {\n\tlet client = Client::new(ClientConfig::new(\"http:\u002F\u002Flocalhost:6420\").namespace(\"default\"));\n\tlet handle = client.get_or_create_typed_default::\u003CCounter>(\"counter\", [\"general\"])?;\n\n\t\u002F\u002F Raw HTTP request\n\tlet response = handle\n\t\t.inner()\n\t\t.fetch(\"history\", Method::GET, HeaderMap::new(), None)\n\t\t.await?;\n\tlet history: Vec\u003CString> = response.json().await?;\n\tprintln!(\"history: {history:?}\");\n\n\t\u002F\u002F Raw WebSocket connection\n\tlet mut ws = handle.inner().web_socket(\"stream\", None).await?;\n\tws.send(Message::text(\"hello\")).await?;\n\tif let Some(message) = ws.next().await {\n\t\tprintln!(\"received: {:?}\", message?);\n\t}\n\n\tOk(())\n}\n```\n\n## Calling from Backend\n\nThe client is a normal Tokio type, so you can hold it in your backend (Axum, Actix, etc.) and call actors from request handlers. The client is `Clone` and cheap to share:\n\n```rust @nocheck\nuse counter::{Counter, Increment};\nuse rivetkit::{\n\tclient::{Client, ClientConfig},\n\tprelude::*,\n\tTypedClientExt,\n};\n\nasync fn increment(client: Client) -> Result\u003Ci64> {\n\tlet counter = client.get_or_create_typed_default::\u003CCounter>(\"counter\", [\"server-counter\"])?;\n\tlet count = counter.send(Increment { amount: 1 }).await?;\n\tOk(count)\n}\n```\n\n## Error Handling\n\nAction and connection calls return `anyhow::Result`. Actor-side errors surface as an `anyhow::Error` carrying the error group, code, message, and metadata:\n\n```rust @nocheck\nuse counter::{Counter, Increment};\nuse rivetkit::{\n\tclient::{Client, ClientConfig},\n\tprelude::*,\n\tTypedClientExt,\n};\n\n#[tokio::main]\nasync fn main() -> Result\u003C()> {\n\tlet client = Client::new(ClientConfig::new(\"http:\u002F\u002Flocalhost:6420\").namespace(\"default\"));\n\tlet counter = client.get_or_create_typed_default::\u003CCounter>(\"counter\", [\"my-counter\"])?;\n\n\tmatch counter.send(Increment { amount: 1 }).await {\n\t\tOk(count) => println!(\"count: {count}\"),\n\t\tErr(error) => eprintln!(\"action failed: {error:#}\"),\n\t}\n\n\tOk(())\n}\n```\n\n## Concepts\n\n### Keys\n\nKeys uniquely identify actor instances. Use compound keys (arrays) for hierarchical addressing:\n\n```rust @nocheck\nuse counter::Counter;\nuse rivetkit::{\n\tclient::{Client, ClientConfig},\n\tprelude::*,\n\tTypedClientExt,\n};\n\n#[tokio::main]\nasync fn main() -> Result\u003C()> {\n\tlet client = Client::new(ClientConfig::new(\"http:\u002F\u002Flocalhost:6420\").namespace(\"default\"));\n\n\t\u002F\u002F Compound key: [org, room]\n\tlet room = client.get_or_create_typed_default::\u003CCounter>(\"counter\", [\"org-acme\", \"general\"])?;\n\tlet actor_id = room.inner().resolve().await?;\n\tprintln!(\"Actor ID: {actor_id}\");\n\n\tOk(())\n}\n```\n\nKeys accept arrays of `&str` or `String` (`[\"org-acme\", \"general\"]`). Don't build keys with string interpolation like `format!(\"org:{user_id}\")` when `user_id` contains user data. Use arrays instead to prevent key injection attacks.\n\n### Configuration\n\n`ClientConfig::new(endpoint)` is a builder. The endpoint is always required; there is no default. Common options:\n\n```rust @nocheck\nuse rivetkit::client::ClientConfig;\n\nlet config = ClientConfig::new(\"http:\u002F\u002Flocalhost:6420\")\n\t.namespace(\"default\")\n\t.token(\"pk_...\")\n\t.pool_name(\"my-pool\")\n\t.header(\"x-custom\", \"value\");\n```\n\n- `namespace` - target namespace (defaults to the engine's configured namespace).\n- `token` - authentication token for the engine.\n- `pool_name` - runner pool to target.\n- `header` \u002F `headers` - extra HTTP headers sent with each request.\n- `max_input_size` - cap on encoded action input size.\n\nFor serverless deployments, set the endpoint to your app's `\u002Fapi\u002Frivet` URL. See [Endpoints](\u002Fdocs\u002Fgeneral\u002Fendpoints) for details.\n\n## API Reference\n\nSee the full client API documentation on [docs.rs\u002Frivetkit-client](https:\u002F\u002Fdocs.rs\u002Frivetkit-client\u002Flatest\u002Frivetkit_client\u002F).\n\n## Need More Than the Client?\n\nIf you need more about Rivet Actors, registries, or server-side RivetKit, add the main skill:\n\n```bash\nnpx skills add rivet-dev\u002Fskills\n```\n\nThen use the `rivetkit` skill for backend guidance.\n\n",{"data":35,"body":36},{"name":4,"description":6},{"type":37,"children":38},"root",[39,48,63,70,75,81,208,214,256,300,306,319,325,337,412,433,439,595,637,643,843,848,854,1153,1202,1208,1221,1407,1413,1424,1576,1589,1595,1608,1811,1860,1866,1926,1979,2227,2233,2246,2340,2346,2366,2509,2515,2522,2527,2664,2708,2714,2725,2787,2852,2873,2879,2892,2898,2903,2934,2946],{"type":40,"tag":41,"props":42,"children":44},"element","h1",{"id":43},"rivetkit-rust-client",[45],{"type":46,"value":47},"text","RivetKit Rust Client",{"type":40,"tag":49,"props":50,"children":51},"p",{},[52,54,61],{"type":46,"value":53},"Use this skill when building Rust clients that connect to Rivet Actors with ",{"type":40,"tag":55,"props":56,"children":58},"code",{"className":57},[],[59],{"type":46,"value":60},"rivetkit::client",{"type":46,"value":62},".",{"type":40,"tag":64,"props":65,"children":67},"h2",{"id":66},"version",[68],{"type":46,"value":69},"Version",{"type":40,"tag":49,"props":71,"children":72},{},[73],{"type":46,"value":74},"RivetKit version: 2.3.7",{"type":40,"tag":64,"props":76,"children":78},{"id":77},"first-steps",[79],{"type":46,"value":80},"First Steps",{"type":40,"tag":82,"props":83,"children":84},"ol",{},[85,188],{"type":40,"tag":86,"props":87,"children":88},"li",{},[89,91],{"type":46,"value":90},"Add the dependency\n",{"type":40,"tag":92,"props":93,"children":98},"pre",{"className":94,"code":95,"language":96,"meta":97,"style":97},"language-sh shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","cargo add rivetkit anyhow async-trait\ncargo add serde --features derive\ncargo add tokio --features full\n","sh","",[99],{"type":40,"tag":55,"props":100,"children":101},{"__ignoreMap":97},[102,135,162],{"type":40,"tag":103,"props":104,"children":107},"span",{"class":105,"line":106},"line",1,[108,114,120,125,130],{"type":40,"tag":103,"props":109,"children":111},{"style":110},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[112],{"type":46,"value":113},"cargo",{"type":40,"tag":103,"props":115,"children":117},{"style":116},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[118],{"type":46,"value":119}," add",{"type":40,"tag":103,"props":121,"children":122},{"style":116},[123],{"type":46,"value":124}," rivetkit",{"type":40,"tag":103,"props":126,"children":127},{"style":116},[128],{"type":46,"value":129}," anyhow",{"type":40,"tag":103,"props":131,"children":132},{"style":116},[133],{"type":46,"value":134}," async-trait\n",{"type":40,"tag":103,"props":136,"children":138},{"class":105,"line":137},2,[139,143,147,152,157],{"type":40,"tag":103,"props":140,"children":141},{"style":110},[142],{"type":46,"value":113},{"type":40,"tag":103,"props":144,"children":145},{"style":116},[146],{"type":46,"value":119},{"type":40,"tag":103,"props":148,"children":149},{"style":116},[150],{"type":46,"value":151}," serde",{"type":40,"tag":103,"props":153,"children":154},{"style":116},[155],{"type":46,"value":156}," --features",{"type":40,"tag":103,"props":158,"children":159},{"style":116},[160],{"type":46,"value":161}," derive\n",{"type":40,"tag":103,"props":163,"children":165},{"class":105,"line":164},3,[166,170,174,179,183],{"type":40,"tag":103,"props":167,"children":168},{"style":110},[169],{"type":46,"value":113},{"type":40,"tag":103,"props":171,"children":172},{"style":116},[173],{"type":46,"value":119},{"type":40,"tag":103,"props":175,"children":176},{"style":116},[177],{"type":46,"value":178}," tokio",{"type":40,"tag":103,"props":180,"children":181},{"style":116},[182],{"type":46,"value":156},{"type":40,"tag":103,"props":184,"children":185},{"style":116},[186],{"type":46,"value":187}," full\n",{"type":40,"tag":86,"props":189,"children":190},{},[191,193,199,201,207],{"type":46,"value":192},"Create a client with ",{"type":40,"tag":55,"props":194,"children":196},{"className":195},[],[197],{"type":46,"value":198},"Client::new(ClientConfig::new(endpoint))",{"type":46,"value":200}," and call typed actions with ",{"type":40,"tag":55,"props":202,"children":204},{"className":203},[],[205],{"type":46,"value":206},"get_or_create_typed_default::\u003CA>(...)",{"type":46,"value":62},{"type":40,"tag":64,"props":209,"children":211},{"id":210},"error-handling-policy",[212],{"type":46,"value":213},"Error Handling Policy",{"type":40,"tag":215,"props":216,"children":217},"ul",{},[218,238,251],{"type":40,"tag":86,"props":219,"children":220},{},[221,223,229,231,237],{"type":46,"value":222},"Prefer fail-fast behavior by default. Propagate ",{"type":40,"tag":55,"props":224,"children":226},{"className":225},[],[227],{"type":46,"value":228},"anyhow::Result",{"type":46,"value":230}," with ",{"type":40,"tag":55,"props":232,"children":234},{"className":233},[],[235],{"type":46,"value":236},"?",{"type":46,"value":62},{"type":40,"tag":86,"props":239,"children":240},{},[241,243,249],{"type":46,"value":242},"Avoid swallowing errors with broad ",{"type":40,"tag":55,"props":244,"children":246},{"className":245},[],[247],{"type":46,"value":248},"match",{"type":46,"value":250}," arms unless absolutely needed.",{"type":40,"tag":86,"props":252,"children":253},{},[254],{"type":46,"value":255},"If an error is handled inline, handle it explicitly, at minimum by logging it.",{"type":40,"tag":49,"props":257,"children":258},{},[259,261,267,269,274,276,285,287,298],{"type":46,"value":260},"Rust support is in beta. The supported public Rust API is ",{"type":40,"tag":55,"props":262,"children":264},{"className":263},[],[265],{"type":46,"value":266},"rivetkit",{"type":46,"value":268}," and ",{"type":40,"tag":55,"props":270,"children":272},{"className":271},[],[273],{"type":46,"value":60},{"type":46,"value":275},"; lower-level crates are internal implementation details and do not carry a stability guarantee. See the full API reference on ",{"type":40,"tag":277,"props":278,"children":282},"a",{"href":279,"rel":280},"https:\u002F\u002Fdocs.rs\u002Frivetkit",[281],"nofollow",[283],{"type":46,"value":284},"docs.rs\u002Frivetkit",{"type":46,"value":286},", or the runnable ",{"type":40,"tag":277,"props":288,"children":291},{"href":289,"rel":290},"https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fhello-world-rust",[281],[292],{"type":40,"tag":55,"props":293,"children":295},{"className":294},[],[296],{"type":46,"value":297},"hello-world-rust",{"type":46,"value":299}," example.",{"type":40,"tag":64,"props":301,"children":303},{"id":302},"getting-started",[304],{"type":46,"value":305},"Getting Started",{"type":40,"tag":49,"props":307,"children":308},{},[309,311,317],{"type":46,"value":310},"See the ",{"type":40,"tag":277,"props":312,"children":314},{"href":313},"\u002Fdocs\u002Factors\u002Fquickstart\u002Frust",[315],{"type":46,"value":316},"Rust quickstart guide",{"type":46,"value":318}," for getting started.",{"type":40,"tag":64,"props":320,"children":322},{"id":321},"install",[323],{"type":46,"value":324},"Install",{"type":40,"tag":49,"props":326,"children":327},{},[328,330,335],{"type":46,"value":329},"Add the ",{"type":40,"tag":55,"props":331,"children":333},{"className":332},[],[334],{"type":46,"value":266},{"type":46,"value":336}," crate and its companions:",{"type":40,"tag":92,"props":338,"children":339},{"className":94,"code":95,"language":96,"meta":97,"style":97},[340],{"type":40,"tag":55,"props":341,"children":342},{"__ignoreMap":97},[343,366,389],{"type":40,"tag":103,"props":344,"children":345},{"class":105,"line":106},[346,350,354,358,362],{"type":40,"tag":103,"props":347,"children":348},{"style":110},[349],{"type":46,"value":113},{"type":40,"tag":103,"props":351,"children":352},{"style":116},[353],{"type":46,"value":119},{"type":40,"tag":103,"props":355,"children":356},{"style":116},[357],{"type":46,"value":124},{"type":40,"tag":103,"props":359,"children":360},{"style":116},[361],{"type":46,"value":129},{"type":40,"tag":103,"props":363,"children":364},{"style":116},[365],{"type":46,"value":134},{"type":40,"tag":103,"props":367,"children":368},{"class":105,"line":137},[369,373,377,381,385],{"type":40,"tag":103,"props":370,"children":371},{"style":110},[372],{"type":46,"value":113},{"type":40,"tag":103,"props":374,"children":375},{"style":116},[376],{"type":46,"value":119},{"type":40,"tag":103,"props":378,"children":379},{"style":116},[380],{"type":46,"value":151},{"type":40,"tag":103,"props":382,"children":383},{"style":116},[384],{"type":46,"value":156},{"type":40,"tag":103,"props":386,"children":387},{"style":116},[388],{"type":46,"value":161},{"type":40,"tag":103,"props":390,"children":391},{"class":105,"line":164},[392,396,400,404,408],{"type":40,"tag":103,"props":393,"children":394},{"style":110},[395],{"type":46,"value":113},{"type":40,"tag":103,"props":397,"children":398},{"style":116},[399],{"type":46,"value":119},{"type":40,"tag":103,"props":401,"children":402},{"style":116},[403],{"type":46,"value":178},{"type":40,"tag":103,"props":405,"children":406},{"style":116},[407],{"type":46,"value":156},{"type":40,"tag":103,"props":409,"children":410},{"style":116},[411],{"type":46,"value":187},{"type":40,"tag":49,"props":413,"children":414},{},[415,417,423,425,431],{"type":46,"value":416},"The Rust client is strongly typed. It shares the same action and event types as your actor, so define your actor in ",{"type":40,"tag":55,"props":418,"children":420},{"className":419},[],[421],{"type":46,"value":422},"src\u002Flib.rs",{"type":46,"value":424}," and import those types from both your server and your client. There is no need to redefine the actor on the client. See ",{"type":40,"tag":277,"props":426,"children":428},{"href":427},"\u002Fdocs\u002Factors\u002Fquickstart\u002Frust#define-your-actor",[429],{"type":46,"value":430},"Define Your Actor",{"type":46,"value":432}," in the quickstart for the actor definition this page builds on.",{"type":40,"tag":64,"props":434,"children":436},{"id":435},"minimal-client",[437],{"type":46,"value":438},"Minimal Client",{"type":40,"tag":92,"props":440,"children":444},{"className":441,"code":442,"language":19,"meta":443,"style":97},"language-rust shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","use counter::{Counter, Increment};\nuse rivetkit::{\n    client::{Client, ClientConfig},\n    prelude::*,\n    TypedClientExt,\n};\n\n#[tokio::main]\nasync fn main() -> Result\u003C()> {\n    let client = Client::new(ClientConfig::new(\"http:\u002F\u002Flocalhost:6420\").namespace(\"default\"));\n\n    let counter = client.get_or_create_typed_default::\u003CCounter>(\"counter\", [\"my-counter\"])?;\n    let count = counter.send(Increment { amount: 1 }).await?;\n    println!(\"New count: {count}\");\n\n    Ok(())\n}\n","@nocheck",[445],{"type":40,"tag":55,"props":446,"children":447},{"__ignoreMap":97},[448,456,464,472,481,490,499,508,517,526,535,543,552,561,570,578,587],{"type":40,"tag":103,"props":449,"children":450},{"class":105,"line":106},[451],{"type":40,"tag":103,"props":452,"children":453},{},[454],{"type":46,"value":455},"use counter::{Counter, Increment};\n",{"type":40,"tag":103,"props":457,"children":458},{"class":105,"line":137},[459],{"type":40,"tag":103,"props":460,"children":461},{},[462],{"type":46,"value":463},"use rivetkit::{\n",{"type":40,"tag":103,"props":465,"children":466},{"class":105,"line":164},[467],{"type":40,"tag":103,"props":468,"children":469},{},[470],{"type":46,"value":471},"    client::{Client, ClientConfig},\n",{"type":40,"tag":103,"props":473,"children":475},{"class":105,"line":474},4,[476],{"type":40,"tag":103,"props":477,"children":478},{},[479],{"type":46,"value":480},"    prelude::*,\n",{"type":40,"tag":103,"props":482,"children":484},{"class":105,"line":483},5,[485],{"type":40,"tag":103,"props":486,"children":487},{},[488],{"type":46,"value":489},"    TypedClientExt,\n",{"type":40,"tag":103,"props":491,"children":493},{"class":105,"line":492},6,[494],{"type":40,"tag":103,"props":495,"children":496},{},[497],{"type":46,"value":498},"};\n",{"type":40,"tag":103,"props":500,"children":501},{"class":105,"line":27},[502],{"type":40,"tag":103,"props":503,"children":505},{"emptyLinePlaceholder":504},true,[506],{"type":46,"value":507},"\n",{"type":40,"tag":103,"props":509,"children":511},{"class":105,"line":510},8,[512],{"type":40,"tag":103,"props":513,"children":514},{},[515],{"type":46,"value":516},"#[tokio::main]\n",{"type":40,"tag":103,"props":518,"children":520},{"class":105,"line":519},9,[521],{"type":40,"tag":103,"props":522,"children":523},{},[524],{"type":46,"value":525},"async fn main() -> Result\u003C()> {\n",{"type":40,"tag":103,"props":527,"children":529},{"class":105,"line":528},10,[530],{"type":40,"tag":103,"props":531,"children":532},{},[533],{"type":46,"value":534},"    let client = Client::new(ClientConfig::new(\"http:\u002F\u002Flocalhost:6420\").namespace(\"default\"));\n",{"type":40,"tag":103,"props":536,"children":538},{"class":105,"line":537},11,[539],{"type":40,"tag":103,"props":540,"children":541},{"emptyLinePlaceholder":504},[542],{"type":46,"value":507},{"type":40,"tag":103,"props":544,"children":546},{"class":105,"line":545},12,[547],{"type":40,"tag":103,"props":548,"children":549},{},[550],{"type":46,"value":551},"    let counter = client.get_or_create_typed_default::\u003CCounter>(\"counter\", [\"my-counter\"])?;\n",{"type":40,"tag":103,"props":553,"children":555},{"class":105,"line":554},13,[556],{"type":40,"tag":103,"props":557,"children":558},{},[559],{"type":46,"value":560},"    let count = counter.send(Increment { amount: 1 }).await?;\n",{"type":40,"tag":103,"props":562,"children":564},{"class":105,"line":563},14,[565],{"type":40,"tag":103,"props":566,"children":567},{},[568],{"type":46,"value":569},"    println!(\"New count: {count}\");\n",{"type":40,"tag":103,"props":571,"children":573},{"class":105,"line":572},15,[574],{"type":40,"tag":103,"props":575,"children":576},{"emptyLinePlaceholder":504},[577],{"type":46,"value":507},{"type":40,"tag":103,"props":579,"children":581},{"class":105,"line":580},16,[582],{"type":40,"tag":103,"props":583,"children":584},{},[585],{"type":46,"value":586},"    Ok(())\n",{"type":40,"tag":103,"props":588,"children":589},{"class":105,"line":23},[590],{"type":40,"tag":103,"props":591,"children":592},{},[593],{"type":46,"value":594},"}\n",{"type":40,"tag":49,"props":596,"children":597},{},[598,604,606,612,614,620,622,628,629,635],{"type":40,"tag":55,"props":599,"children":601},{"className":600},[],[602],{"type":46,"value":603},"counter",{"type":46,"value":605}," here is your crate name (the package ",{"type":40,"tag":55,"props":607,"children":609},{"className":608},[],[610],{"type":46,"value":611},"name",{"type":46,"value":613}," in ",{"type":40,"tag":55,"props":615,"children":617},{"className":616},[],[618],{"type":46,"value":619},"Cargo.toml",{"type":46,"value":621},", with dashes as underscores). ",{"type":40,"tag":55,"props":623,"children":625},{"className":624},[],[626],{"type":46,"value":627},"Counter",{"type":46,"value":268},{"type":40,"tag":55,"props":630,"children":632},{"className":631},[],[633],{"type":46,"value":634},"Increment",{"type":46,"value":636}," are the types you defined alongside your actor.",{"type":40,"tag":64,"props":638,"children":640},{"id":639},"stateless-vs-stateful",[641],{"type":46,"value":642},"Stateless vs Stateful",{"type":40,"tag":92,"props":644,"children":646},{"className":441,"code":645,"language":19,"meta":443,"style":97},"use counter::{Counter, Increment, NewCount};\nuse rivetkit::{\n    client::{Client, ClientConfig},\n    prelude::*,\n    TypedClientExt,\n};\n\n#[tokio::main]\nasync fn main() -> Result\u003C()> {\n    let client = Client::new(ClientConfig::new(\"http:\u002F\u002Flocalhost:6420\").namespace(\"default\"));\n    let counter = client.get_or_create_typed_default::\u003CCounter>(\"counter\", [\"my-counter\"])?;\n\n    \u002F\u002F Stateless: each call is independent\n    counter.send(Increment { amount: 1 }).await?;\n\n    \u002F\u002F Stateful: keep a connection open for realtime events\n    let connection = counter.connect();\n    connection\n        .on::\u003CNewCount>(|event| println!(\"count: {}\", event.count))\n        .await;\n    connection.send(Increment { amount: 1 }).await?;\n\n    connection.disconnect().await;\n    Ok(())\n}\n",[647],{"type":40,"tag":55,"props":648,"children":649},{"__ignoreMap":97},[650,658,665,672,679,686,693,700,707,714,721,728,735,743,751,758,766,774,783,792,801,810,818,827,835],{"type":40,"tag":103,"props":651,"children":652},{"class":105,"line":106},[653],{"type":40,"tag":103,"props":654,"children":655},{},[656],{"type":46,"value":657},"use counter::{Counter, Increment, NewCount};\n",{"type":40,"tag":103,"props":659,"children":660},{"class":105,"line":137},[661],{"type":40,"tag":103,"props":662,"children":663},{},[664],{"type":46,"value":463},{"type":40,"tag":103,"props":666,"children":667},{"class":105,"line":164},[668],{"type":40,"tag":103,"props":669,"children":670},{},[671],{"type":46,"value":471},{"type":40,"tag":103,"props":673,"children":674},{"class":105,"line":474},[675],{"type":40,"tag":103,"props":676,"children":677},{},[678],{"type":46,"value":480},{"type":40,"tag":103,"props":680,"children":681},{"class":105,"line":483},[682],{"type":40,"tag":103,"props":683,"children":684},{},[685],{"type":46,"value":489},{"type":40,"tag":103,"props":687,"children":688},{"class":105,"line":492},[689],{"type":40,"tag":103,"props":690,"children":691},{},[692],{"type":46,"value":498},{"type":40,"tag":103,"props":694,"children":695},{"class":105,"line":27},[696],{"type":40,"tag":103,"props":697,"children":698},{"emptyLinePlaceholder":504},[699],{"type":46,"value":507},{"type":40,"tag":103,"props":701,"children":702},{"class":105,"line":510},[703],{"type":40,"tag":103,"props":704,"children":705},{},[706],{"type":46,"value":516},{"type":40,"tag":103,"props":708,"children":709},{"class":105,"line":519},[710],{"type":40,"tag":103,"props":711,"children":712},{},[713],{"type":46,"value":525},{"type":40,"tag":103,"props":715,"children":716},{"class":105,"line":528},[717],{"type":40,"tag":103,"props":718,"children":719},{},[720],{"type":46,"value":534},{"type":40,"tag":103,"props":722,"children":723},{"class":105,"line":537},[724],{"type":40,"tag":103,"props":725,"children":726},{},[727],{"type":46,"value":551},{"type":40,"tag":103,"props":729,"children":730},{"class":105,"line":545},[731],{"type":40,"tag":103,"props":732,"children":733},{"emptyLinePlaceholder":504},[734],{"type":46,"value":507},{"type":40,"tag":103,"props":736,"children":737},{"class":105,"line":554},[738],{"type":40,"tag":103,"props":739,"children":740},{},[741],{"type":46,"value":742},"    \u002F\u002F Stateless: each call is independent\n",{"type":40,"tag":103,"props":744,"children":745},{"class":105,"line":563},[746],{"type":40,"tag":103,"props":747,"children":748},{},[749],{"type":46,"value":750},"    counter.send(Increment { amount: 1 }).await?;\n",{"type":40,"tag":103,"props":752,"children":753},{"class":105,"line":572},[754],{"type":40,"tag":103,"props":755,"children":756},{"emptyLinePlaceholder":504},[757],{"type":46,"value":507},{"type":40,"tag":103,"props":759,"children":760},{"class":105,"line":580},[761],{"type":40,"tag":103,"props":762,"children":763},{},[764],{"type":46,"value":765},"    \u002F\u002F Stateful: keep a connection open for realtime events\n",{"type":40,"tag":103,"props":767,"children":768},{"class":105,"line":23},[769],{"type":40,"tag":103,"props":770,"children":771},{},[772],{"type":46,"value":773},"    let connection = counter.connect();\n",{"type":40,"tag":103,"props":775,"children":777},{"class":105,"line":776},18,[778],{"type":40,"tag":103,"props":779,"children":780},{},[781],{"type":46,"value":782},"    connection\n",{"type":40,"tag":103,"props":784,"children":786},{"class":105,"line":785},19,[787],{"type":40,"tag":103,"props":788,"children":789},{},[790],{"type":46,"value":791},"        .on::\u003CNewCount>(|event| println!(\"count: {}\", event.count))\n",{"type":40,"tag":103,"props":793,"children":795},{"class":105,"line":794},20,[796],{"type":40,"tag":103,"props":797,"children":798},{},[799],{"type":46,"value":800},"        .await;\n",{"type":40,"tag":103,"props":802,"children":804},{"class":105,"line":803},21,[805],{"type":40,"tag":103,"props":806,"children":807},{},[808],{"type":46,"value":809},"    connection.send(Increment { amount: 1 }).await?;\n",{"type":40,"tag":103,"props":811,"children":813},{"class":105,"line":812},22,[814],{"type":40,"tag":103,"props":815,"children":816},{"emptyLinePlaceholder":504},[817],{"type":46,"value":507},{"type":40,"tag":103,"props":819,"children":821},{"class":105,"line":820},23,[822],{"type":40,"tag":103,"props":823,"children":824},{},[825],{"type":46,"value":826},"    connection.disconnect().await;\n",{"type":40,"tag":103,"props":828,"children":830},{"class":105,"line":829},24,[831],{"type":40,"tag":103,"props":832,"children":833},{},[834],{"type":46,"value":586},{"type":40,"tag":103,"props":836,"children":838},{"class":105,"line":837},25,[839],{"type":40,"tag":103,"props":840,"children":841},{},[842],{"type":46,"value":594},{"type":40,"tag":49,"props":844,"children":845},{},[846],{"type":46,"value":847},"A stateless call on the handle opens a short-lived request per action. A connection keeps a WebSocket open so you can receive events and reuse it across calls.",{"type":40,"tag":64,"props":849,"children":851},{"id":850},"getting-actors",[852],{"type":46,"value":853},"Getting Actors",{"type":40,"tag":92,"props":855,"children":857},{"className":441,"code":856,"language":19,"meta":443,"style":97},"use counter::Counter;\nuse rivetkit::{\n    client::{Client, ClientConfig, GetOrCreateOptions},\n    prelude::*,\n    TypedClientExt,\n};\nuse serde_json::json;\n\n#[tokio::main]\nasync fn main() -> Result\u003C()> {\n    let client = Client::new(ClientConfig::new(\"http:\u002F\u002Flocalhost:6420\").namespace(\"default\"));\n\n    \u002F\u002F Get or create an actor\n    let room = client.get_or_create_typed_default::\u003CCounter>(\"counter\", [\"room-42\"])?;\n\n    \u002F\u002F Get an existing actor handle (fails when used if the actor does not exist)\n    let existing = client.get_typed_default::\u003CCounter>(\"counter\", [\"room-42\"])?;\n\n    \u002F\u002F Create a new actor with input\n    let created = client.get_or_create_typed::\u003CCounter>(\n        \"counter\",\n        [\"game-1\"],\n        GetOrCreateOptions {\n            create_with_input: Some(json!({ \"mode\": \"ranked\" })),\n            ..Default::default()\n        },\n    )?;\n\n    \u002F\u002F Get an actor handle by ID\n    let by_id = client.get_for_id(\"counter\", \"actor-id\", Default::default())?;\n\n    \u002F\u002F Resolve the actor ID\n    let resolved_id = room.inner().resolve().await?;\n    println!(\"Resolved ID: {resolved_id}\");\n\n    Ok(())\n}\n",[858],{"type":40,"tag":55,"props":859,"children":860},{"__ignoreMap":97},[861,869,876,884,891,898,905,913,920,927,934,941,948,956,964,971,979,987,994,1002,1010,1018,1026,1034,1042,1050,1059,1068,1076,1085,1094,1102,1111,1120,1129,1137,1145],{"type":40,"tag":103,"props":862,"children":863},{"class":105,"line":106},[864],{"type":40,"tag":103,"props":865,"children":866},{},[867],{"type":46,"value":868},"use counter::Counter;\n",{"type":40,"tag":103,"props":870,"children":871},{"class":105,"line":137},[872],{"type":40,"tag":103,"props":873,"children":874},{},[875],{"type":46,"value":463},{"type":40,"tag":103,"props":877,"children":878},{"class":105,"line":164},[879],{"type":40,"tag":103,"props":880,"children":881},{},[882],{"type":46,"value":883},"    client::{Client, ClientConfig, GetOrCreateOptions},\n",{"type":40,"tag":103,"props":885,"children":886},{"class":105,"line":474},[887],{"type":40,"tag":103,"props":888,"children":889},{},[890],{"type":46,"value":480},{"type":40,"tag":103,"props":892,"children":893},{"class":105,"line":483},[894],{"type":40,"tag":103,"props":895,"children":896},{},[897],{"type":46,"value":489},{"type":40,"tag":103,"props":899,"children":900},{"class":105,"line":492},[901],{"type":40,"tag":103,"props":902,"children":903},{},[904],{"type":46,"value":498},{"type":40,"tag":103,"props":906,"children":907},{"class":105,"line":27},[908],{"type":40,"tag":103,"props":909,"children":910},{},[911],{"type":46,"value":912},"use serde_json::json;\n",{"type":40,"tag":103,"props":914,"children":915},{"class":105,"line":510},[916],{"type":40,"tag":103,"props":917,"children":918},{"emptyLinePlaceholder":504},[919],{"type":46,"value":507},{"type":40,"tag":103,"props":921,"children":922},{"class":105,"line":519},[923],{"type":40,"tag":103,"props":924,"children":925},{},[926],{"type":46,"value":516},{"type":40,"tag":103,"props":928,"children":929},{"class":105,"line":528},[930],{"type":40,"tag":103,"props":931,"children":932},{},[933],{"type":46,"value":525},{"type":40,"tag":103,"props":935,"children":936},{"class":105,"line":537},[937],{"type":40,"tag":103,"props":938,"children":939},{},[940],{"type":46,"value":534},{"type":40,"tag":103,"props":942,"children":943},{"class":105,"line":545},[944],{"type":40,"tag":103,"props":945,"children":946},{"emptyLinePlaceholder":504},[947],{"type":46,"value":507},{"type":40,"tag":103,"props":949,"children":950},{"class":105,"line":554},[951],{"type":40,"tag":103,"props":952,"children":953},{},[954],{"type":46,"value":955},"    \u002F\u002F Get or create an actor\n",{"type":40,"tag":103,"props":957,"children":958},{"class":105,"line":563},[959],{"type":40,"tag":103,"props":960,"children":961},{},[962],{"type":46,"value":963},"    let room = client.get_or_create_typed_default::\u003CCounter>(\"counter\", [\"room-42\"])?;\n",{"type":40,"tag":103,"props":965,"children":966},{"class":105,"line":572},[967],{"type":40,"tag":103,"props":968,"children":969},{"emptyLinePlaceholder":504},[970],{"type":46,"value":507},{"type":40,"tag":103,"props":972,"children":973},{"class":105,"line":580},[974],{"type":40,"tag":103,"props":975,"children":976},{},[977],{"type":46,"value":978},"    \u002F\u002F Get an existing actor handle (fails when used if the actor does not exist)\n",{"type":40,"tag":103,"props":980,"children":981},{"class":105,"line":23},[982],{"type":40,"tag":103,"props":983,"children":984},{},[985],{"type":46,"value":986},"    let existing = client.get_typed_default::\u003CCounter>(\"counter\", [\"room-42\"])?;\n",{"type":40,"tag":103,"props":988,"children":989},{"class":105,"line":776},[990],{"type":40,"tag":103,"props":991,"children":992},{"emptyLinePlaceholder":504},[993],{"type":46,"value":507},{"type":40,"tag":103,"props":995,"children":996},{"class":105,"line":785},[997],{"type":40,"tag":103,"props":998,"children":999},{},[1000],{"type":46,"value":1001},"    \u002F\u002F Create a new actor with input\n",{"type":40,"tag":103,"props":1003,"children":1004},{"class":105,"line":794},[1005],{"type":40,"tag":103,"props":1006,"children":1007},{},[1008],{"type":46,"value":1009},"    let created = client.get_or_create_typed::\u003CCounter>(\n",{"type":40,"tag":103,"props":1011,"children":1012},{"class":105,"line":803},[1013],{"type":40,"tag":103,"props":1014,"children":1015},{},[1016],{"type":46,"value":1017},"        \"counter\",\n",{"type":40,"tag":103,"props":1019,"children":1020},{"class":105,"line":812},[1021],{"type":40,"tag":103,"props":1022,"children":1023},{},[1024],{"type":46,"value":1025},"        [\"game-1\"],\n",{"type":40,"tag":103,"props":1027,"children":1028},{"class":105,"line":820},[1029],{"type":40,"tag":103,"props":1030,"children":1031},{},[1032],{"type":46,"value":1033},"        GetOrCreateOptions {\n",{"type":40,"tag":103,"props":1035,"children":1036},{"class":105,"line":829},[1037],{"type":40,"tag":103,"props":1038,"children":1039},{},[1040],{"type":46,"value":1041},"            create_with_input: Some(json!({ \"mode\": \"ranked\" })),\n",{"type":40,"tag":103,"props":1043,"children":1044},{"class":105,"line":837},[1045],{"type":40,"tag":103,"props":1046,"children":1047},{},[1048],{"type":46,"value":1049},"            ..Default::default()\n",{"type":40,"tag":103,"props":1051,"children":1053},{"class":105,"line":1052},26,[1054],{"type":40,"tag":103,"props":1055,"children":1056},{},[1057],{"type":46,"value":1058},"        },\n",{"type":40,"tag":103,"props":1060,"children":1062},{"class":105,"line":1061},27,[1063],{"type":40,"tag":103,"props":1064,"children":1065},{},[1066],{"type":46,"value":1067},"    )?;\n",{"type":40,"tag":103,"props":1069,"children":1071},{"class":105,"line":1070},28,[1072],{"type":40,"tag":103,"props":1073,"children":1074},{"emptyLinePlaceholder":504},[1075],{"type":46,"value":507},{"type":40,"tag":103,"props":1077,"children":1079},{"class":105,"line":1078},29,[1080],{"type":40,"tag":103,"props":1081,"children":1082},{},[1083],{"type":46,"value":1084},"    \u002F\u002F Get an actor handle by ID\n",{"type":40,"tag":103,"props":1086,"children":1088},{"class":105,"line":1087},30,[1089],{"type":40,"tag":103,"props":1090,"children":1091},{},[1092],{"type":46,"value":1093},"    let by_id = client.get_for_id(\"counter\", \"actor-id\", Default::default())?;\n",{"type":40,"tag":103,"props":1095,"children":1097},{"class":105,"line":1096},31,[1098],{"type":40,"tag":103,"props":1099,"children":1100},{"emptyLinePlaceholder":504},[1101],{"type":46,"value":507},{"type":40,"tag":103,"props":1103,"children":1105},{"class":105,"line":1104},32,[1106],{"type":40,"tag":103,"props":1107,"children":1108},{},[1109],{"type":46,"value":1110},"    \u002F\u002F Resolve the actor ID\n",{"type":40,"tag":103,"props":1112,"children":1114},{"class":105,"line":1113},33,[1115],{"type":40,"tag":103,"props":1116,"children":1117},{},[1118],{"type":46,"value":1119},"    let resolved_id = room.inner().resolve().await?;\n",{"type":40,"tag":103,"props":1121,"children":1123},{"class":105,"line":1122},34,[1124],{"type":40,"tag":103,"props":1125,"children":1126},{},[1127],{"type":46,"value":1128},"    println!(\"Resolved ID: {resolved_id}\");\n",{"type":40,"tag":103,"props":1130,"children":1132},{"class":105,"line":1131},35,[1133],{"type":40,"tag":103,"props":1134,"children":1135},{"emptyLinePlaceholder":504},[1136],{"type":46,"value":507},{"type":40,"tag":103,"props":1138,"children":1140},{"class":105,"line":1139},36,[1141],{"type":40,"tag":103,"props":1142,"children":1143},{},[1144],{"type":46,"value":586},{"type":40,"tag":103,"props":1146,"children":1148},{"class":105,"line":1147},37,[1149],{"type":40,"tag":103,"props":1150,"children":1151},{},[1152],{"type":46,"value":594},{"type":40,"tag":49,"props":1154,"children":1155},{},[1156,1162,1164,1170,1172,1178,1179,1185,1187,1193,1194,1200],{"type":40,"tag":55,"props":1157,"children":1159},{"className":1158},[],[1160],{"type":46,"value":1161},"get_typed_default",{"type":46,"value":1163}," \u002F ",{"type":40,"tag":55,"props":1165,"children":1167},{"className":1166},[],[1168],{"type":46,"value":1169},"get_or_create_typed_default",{"type":46,"value":1171}," use default options. The non-default variants (",{"type":40,"tag":55,"props":1173,"children":1175},{"className":1174},[],[1176],{"type":46,"value":1177},"get_typed",{"type":46,"value":1163},{"type":40,"tag":55,"props":1180,"children":1182},{"className":1181},[],[1183],{"type":46,"value":1184},"get_or_create_typed",{"type":46,"value":1186},") take ",{"type":40,"tag":55,"props":1188,"children":1190},{"className":1189},[],[1191],{"type":46,"value":1192},"GetOptions",{"type":46,"value":1163},{"type":40,"tag":55,"props":1195,"children":1197},{"className":1196},[],[1198],{"type":46,"value":1199},"GetOrCreateOptions",{"type":46,"value":1201}," for connection parameters, input, and region.",{"type":40,"tag":64,"props":1203,"children":1205},{"id":1204},"connection-parameters",[1206],{"type":46,"value":1207},"Connection Parameters",{"type":40,"tag":49,"props":1209,"children":1210},{},[1211,1213,1219],{"type":46,"value":1212},"Pass connection parameters through the handle options. They are delivered to the actor's ",{"type":40,"tag":55,"props":1214,"children":1216},{"className":1215},[],[1217],{"type":46,"value":1218},"create_conn_state",{"type":46,"value":1220}," callback:",{"type":40,"tag":92,"props":1222,"children":1224},{"className":441,"code":1223,"language":19,"meta":443,"style":97},"use counter::Counter;\nuse rivetkit::{\n    client::{Client, ClientConfig, GetOrCreateOptions},\n    prelude::*,\n    TypedClientExt,\n};\nuse serde_json::json;\n\n#[tokio::main]\nasync fn main() -> Result\u003C()> {\n    let client = Client::new(ClientConfig::new(\"http:\u002F\u002Flocalhost:6420\").namespace(\"default\"));\n\n    let chat = client.get_or_create_typed::\u003CCounter>(\n        \"counter\",\n        [\"general\"],\n        GetOrCreateOptions {\n            params: Some(json!({ \"authToken\": \"jwt-token-here\" })),\n            ..Default::default()\n        },\n    )?;\n\n    let connection = chat.connect();\n    connection.disconnect().await;\n    Ok(())\n}\n",[1225],{"type":40,"tag":55,"props":1226,"children":1227},{"__ignoreMap":97},[1228,1235,1242,1249,1256,1263,1270,1277,1284,1291,1298,1305,1312,1320,1327,1335,1342,1350,1357,1364,1371,1378,1386,1393,1400],{"type":40,"tag":103,"props":1229,"children":1230},{"class":105,"line":106},[1231],{"type":40,"tag":103,"props":1232,"children":1233},{},[1234],{"type":46,"value":868},{"type":40,"tag":103,"props":1236,"children":1237},{"class":105,"line":137},[1238],{"type":40,"tag":103,"props":1239,"children":1240},{},[1241],{"type":46,"value":463},{"type":40,"tag":103,"props":1243,"children":1244},{"class":105,"line":164},[1245],{"type":40,"tag":103,"props":1246,"children":1247},{},[1248],{"type":46,"value":883},{"type":40,"tag":103,"props":1250,"children":1251},{"class":105,"line":474},[1252],{"type":40,"tag":103,"props":1253,"children":1254},{},[1255],{"type":46,"value":480},{"type":40,"tag":103,"props":1257,"children":1258},{"class":105,"line":483},[1259],{"type":40,"tag":103,"props":1260,"children":1261},{},[1262],{"type":46,"value":489},{"type":40,"tag":103,"props":1264,"children":1265},{"class":105,"line":492},[1266],{"type":40,"tag":103,"props":1267,"children":1268},{},[1269],{"type":46,"value":498},{"type":40,"tag":103,"props":1271,"children":1272},{"class":105,"line":27},[1273],{"type":40,"tag":103,"props":1274,"children":1275},{},[1276],{"type":46,"value":912},{"type":40,"tag":103,"props":1278,"children":1279},{"class":105,"line":510},[1280],{"type":40,"tag":103,"props":1281,"children":1282},{"emptyLinePlaceholder":504},[1283],{"type":46,"value":507},{"type":40,"tag":103,"props":1285,"children":1286},{"class":105,"line":519},[1287],{"type":40,"tag":103,"props":1288,"children":1289},{},[1290],{"type":46,"value":516},{"type":40,"tag":103,"props":1292,"children":1293},{"class":105,"line":528},[1294],{"type":40,"tag":103,"props":1295,"children":1296},{},[1297],{"type":46,"value":525},{"type":40,"tag":103,"props":1299,"children":1300},{"class":105,"line":537},[1301],{"type":40,"tag":103,"props":1302,"children":1303},{},[1304],{"type":46,"value":534},{"type":40,"tag":103,"props":1306,"children":1307},{"class":105,"line":545},[1308],{"type":40,"tag":103,"props":1309,"children":1310},{"emptyLinePlaceholder":504},[1311],{"type":46,"value":507},{"type":40,"tag":103,"props":1313,"children":1314},{"class":105,"line":554},[1315],{"type":40,"tag":103,"props":1316,"children":1317},{},[1318],{"type":46,"value":1319},"    let chat = client.get_or_create_typed::\u003CCounter>(\n",{"type":40,"tag":103,"props":1321,"children":1322},{"class":105,"line":563},[1323],{"type":40,"tag":103,"props":1324,"children":1325},{},[1326],{"type":46,"value":1017},{"type":40,"tag":103,"props":1328,"children":1329},{"class":105,"line":572},[1330],{"type":40,"tag":103,"props":1331,"children":1332},{},[1333],{"type":46,"value":1334},"        [\"general\"],\n",{"type":40,"tag":103,"props":1336,"children":1337},{"class":105,"line":580},[1338],{"type":40,"tag":103,"props":1339,"children":1340},{},[1341],{"type":46,"value":1033},{"type":40,"tag":103,"props":1343,"children":1344},{"class":105,"line":23},[1345],{"type":40,"tag":103,"props":1346,"children":1347},{},[1348],{"type":46,"value":1349},"            params: Some(json!({ \"authToken\": \"jwt-token-here\" })),\n",{"type":40,"tag":103,"props":1351,"children":1352},{"class":105,"line":776},[1353],{"type":40,"tag":103,"props":1354,"children":1355},{},[1356],{"type":46,"value":1049},{"type":40,"tag":103,"props":1358,"children":1359},{"class":105,"line":785},[1360],{"type":40,"tag":103,"props":1361,"children":1362},{},[1363],{"type":46,"value":1058},{"type":40,"tag":103,"props":1365,"children":1366},{"class":105,"line":794},[1367],{"type":40,"tag":103,"props":1368,"children":1369},{},[1370],{"type":46,"value":1067},{"type":40,"tag":103,"props":1372,"children":1373},{"class":105,"line":803},[1374],{"type":40,"tag":103,"props":1375,"children":1376},{"emptyLinePlaceholder":504},[1377],{"type":46,"value":507},{"type":40,"tag":103,"props":1379,"children":1380},{"class":105,"line":812},[1381],{"type":40,"tag":103,"props":1382,"children":1383},{},[1384],{"type":46,"value":1385},"    let connection = chat.connect();\n",{"type":40,"tag":103,"props":1387,"children":1388},{"class":105,"line":820},[1389],{"type":40,"tag":103,"props":1390,"children":1391},{},[1392],{"type":46,"value":826},{"type":40,"tag":103,"props":1394,"children":1395},{"class":105,"line":829},[1396],{"type":40,"tag":103,"props":1397,"children":1398},{},[1399],{"type":46,"value":586},{"type":40,"tag":103,"props":1401,"children":1402},{"class":105,"line":837},[1403],{"type":40,"tag":103,"props":1404,"children":1405},{},[1406],{"type":46,"value":594},{"type":40,"tag":64,"props":1408,"children":1410},{"id":1409},"subscribing-to-events",[1411],{"type":46,"value":1412},"Subscribing to Events",{"type":40,"tag":49,"props":1414,"children":1415},{},[1416,1422],{"type":40,"tag":55,"props":1417,"children":1419},{"className":1418},[],[1420],{"type":46,"value":1421},"on",{"type":46,"value":1423}," registers a typed callback for an event and returns once the subscription is registered:",{"type":40,"tag":92,"props":1425,"children":1427},{"className":441,"code":1426,"language":19,"meta":443,"style":97},"use counter::{Counter, NewCount};\nuse rivetkit::{\n    client::{Client, ClientConfig},\n    prelude::*,\n    TypedClientExt,\n};\n\n#[tokio::main]\nasync fn main() -> Result\u003C()> {\n    let client = Client::new(ClientConfig::new(\"http:\u002F\u002Flocalhost:6420\").namespace(\"default\"));\n    let connection = client\n        .get_or_create_typed_default::\u003CCounter>(\"counter\", [\"general\"])?\n        .connect();\n\n    connection\n        .on::\u003CNewCount>(|event| println!(\"count changed: {}\", event.count))\n        .await;\n\n    Ok(())\n}\n",[1428],{"type":40,"tag":55,"props":1429,"children":1430},{"__ignoreMap":97},[1431,1439,1446,1453,1460,1467,1474,1481,1488,1495,1502,1510,1518,1526,1533,1540,1548,1555,1562,1569],{"type":40,"tag":103,"props":1432,"children":1433},{"class":105,"line":106},[1434],{"type":40,"tag":103,"props":1435,"children":1436},{},[1437],{"type":46,"value":1438},"use counter::{Counter, NewCount};\n",{"type":40,"tag":103,"props":1440,"children":1441},{"class":105,"line":137},[1442],{"type":40,"tag":103,"props":1443,"children":1444},{},[1445],{"type":46,"value":463},{"type":40,"tag":103,"props":1447,"children":1448},{"class":105,"line":164},[1449],{"type":40,"tag":103,"props":1450,"children":1451},{},[1452],{"type":46,"value":471},{"type":40,"tag":103,"props":1454,"children":1455},{"class":105,"line":474},[1456],{"type":40,"tag":103,"props":1457,"children":1458},{},[1459],{"type":46,"value":480},{"type":40,"tag":103,"props":1461,"children":1462},{"class":105,"line":483},[1463],{"type":40,"tag":103,"props":1464,"children":1465},{},[1466],{"type":46,"value":489},{"type":40,"tag":103,"props":1468,"children":1469},{"class":105,"line":492},[1470],{"type":40,"tag":103,"props":1471,"children":1472},{},[1473],{"type":46,"value":498},{"type":40,"tag":103,"props":1475,"children":1476},{"class":105,"line":27},[1477],{"type":40,"tag":103,"props":1478,"children":1479},{"emptyLinePlaceholder":504},[1480],{"type":46,"value":507},{"type":40,"tag":103,"props":1482,"children":1483},{"class":105,"line":510},[1484],{"type":40,"tag":103,"props":1485,"children":1486},{},[1487],{"type":46,"value":516},{"type":40,"tag":103,"props":1489,"children":1490},{"class":105,"line":519},[1491],{"type":40,"tag":103,"props":1492,"children":1493},{},[1494],{"type":46,"value":525},{"type":40,"tag":103,"props":1496,"children":1497},{"class":105,"line":528},[1498],{"type":40,"tag":103,"props":1499,"children":1500},{},[1501],{"type":46,"value":534},{"type":40,"tag":103,"props":1503,"children":1504},{"class":105,"line":537},[1505],{"type":40,"tag":103,"props":1506,"children":1507},{},[1508],{"type":46,"value":1509},"    let connection = client\n",{"type":40,"tag":103,"props":1511,"children":1512},{"class":105,"line":545},[1513],{"type":40,"tag":103,"props":1514,"children":1515},{},[1516],{"type":46,"value":1517},"        .get_or_create_typed_default::\u003CCounter>(\"counter\", [\"general\"])?\n",{"type":40,"tag":103,"props":1519,"children":1520},{"class":105,"line":554},[1521],{"type":40,"tag":103,"props":1522,"children":1523},{},[1524],{"type":46,"value":1525},"        .connect();\n",{"type":40,"tag":103,"props":1527,"children":1528},{"class":105,"line":563},[1529],{"type":40,"tag":103,"props":1530,"children":1531},{"emptyLinePlaceholder":504},[1532],{"type":46,"value":507},{"type":40,"tag":103,"props":1534,"children":1535},{"class":105,"line":572},[1536],{"type":40,"tag":103,"props":1537,"children":1538},{},[1539],{"type":46,"value":782},{"type":40,"tag":103,"props":1541,"children":1542},{"class":105,"line":580},[1543],{"type":40,"tag":103,"props":1544,"children":1545},{},[1546],{"type":46,"value":1547},"        .on::\u003CNewCount>(|event| println!(\"count changed: {}\", event.count))\n",{"type":40,"tag":103,"props":1549,"children":1550},{"class":105,"line":23},[1551],{"type":40,"tag":103,"props":1552,"children":1553},{},[1554],{"type":46,"value":800},{"type":40,"tag":103,"props":1556,"children":1557},{"class":105,"line":776},[1558],{"type":40,"tag":103,"props":1559,"children":1560},{"emptyLinePlaceholder":504},[1561],{"type":46,"value":507},{"type":40,"tag":103,"props":1563,"children":1564},{"class":105,"line":785},[1565],{"type":40,"tag":103,"props":1566,"children":1567},{},[1568],{"type":46,"value":586},{"type":40,"tag":103,"props":1570,"children":1571},{"class":105,"line":794},[1572],{"type":40,"tag":103,"props":1573,"children":1574},{},[1575],{"type":46,"value":594},{"type":40,"tag":49,"props":1577,"children":1578},{},[1579,1581,1587],{"type":46,"value":1580},"Event callbacks are synchronous and run for every matching event. The actor's emitted event type (here ",{"type":40,"tag":55,"props":1582,"children":1584},{"className":1583},[],[1585],{"type":46,"value":1586},"NewCount",{"type":46,"value":1588},") is decoded into the typed value for you.",{"type":40,"tag":64,"props":1590,"children":1592},{"id":1591},"connection-lifecycle",[1593],{"type":46,"value":1594},"Connection Lifecycle",{"type":40,"tag":49,"props":1596,"children":1597},{},[1598,1600,1606],{"type":46,"value":1599},"The lower-level connection exposes lifecycle callbacks and the current status. Reach it with ",{"type":40,"tag":55,"props":1601,"children":1603},{"className":1602},[],[1604],{"type":46,"value":1605},"connection.inner()",{"type":46,"value":1607},":",{"type":40,"tag":92,"props":1609,"children":1611},{"className":441,"code":1610,"language":19,"meta":443,"style":97},"use counter::Counter;\nuse rivetkit::{\n    client::{Client, ClientConfig},\n    prelude::*,\n    TypedClientExt,\n};\n\n#[tokio::main]\nasync fn main() -> Result\u003C()> {\n    let client = Client::new(ClientConfig::new(\"http:\u002F\u002Flocalhost:6420\").namespace(\"default\"));\n    let connection = client\n        .get_or_create_typed_default::\u003CCounter>(\"counter\", [\"general\"])?\n        .connect();\n    let inner = connection.inner().clone();\n\n    inner.on_open(|| println!(\"connected\")).await;\n    inner.on_close(|| println!(\"disconnected\")).await;\n    inner.on_error(|message| eprintln!(\"error: {message}\")).await;\n    inner\n        .on_status_change(|status| println!(\"status: {status:?}\"))\n        .await;\n\n    println!(\"current status: {:?}\", inner.conn_status());\n\n    connection.disconnect().await;\n    Ok(())\n}\n",[1612],{"type":40,"tag":55,"props":1613,"children":1614},{"__ignoreMap":97},[1615,1622,1629,1636,1643,1650,1657,1664,1671,1678,1685,1692,1699,1706,1714,1721,1729,1737,1745,1753,1761,1768,1775,1783,1790,1797,1804],{"type":40,"tag":103,"props":1616,"children":1617},{"class":105,"line":106},[1618],{"type":40,"tag":103,"props":1619,"children":1620},{},[1621],{"type":46,"value":868},{"type":40,"tag":103,"props":1623,"children":1624},{"class":105,"line":137},[1625],{"type":40,"tag":103,"props":1626,"children":1627},{},[1628],{"type":46,"value":463},{"type":40,"tag":103,"props":1630,"children":1631},{"class":105,"line":164},[1632],{"type":40,"tag":103,"props":1633,"children":1634},{},[1635],{"type":46,"value":471},{"type":40,"tag":103,"props":1637,"children":1638},{"class":105,"line":474},[1639],{"type":40,"tag":103,"props":1640,"children":1641},{},[1642],{"type":46,"value":480},{"type":40,"tag":103,"props":1644,"children":1645},{"class":105,"line":483},[1646],{"type":40,"tag":103,"props":1647,"children":1648},{},[1649],{"type":46,"value":489},{"type":40,"tag":103,"props":1651,"children":1652},{"class":105,"line":492},[1653],{"type":40,"tag":103,"props":1654,"children":1655},{},[1656],{"type":46,"value":498},{"type":40,"tag":103,"props":1658,"children":1659},{"class":105,"line":27},[1660],{"type":40,"tag":103,"props":1661,"children":1662},{"emptyLinePlaceholder":504},[1663],{"type":46,"value":507},{"type":40,"tag":103,"props":1665,"children":1666},{"class":105,"line":510},[1667],{"type":40,"tag":103,"props":1668,"children":1669},{},[1670],{"type":46,"value":516},{"type":40,"tag":103,"props":1672,"children":1673},{"class":105,"line":519},[1674],{"type":40,"tag":103,"props":1675,"children":1676},{},[1677],{"type":46,"value":525},{"type":40,"tag":103,"props":1679,"children":1680},{"class":105,"line":528},[1681],{"type":40,"tag":103,"props":1682,"children":1683},{},[1684],{"type":46,"value":534},{"type":40,"tag":103,"props":1686,"children":1687},{"class":105,"line":537},[1688],{"type":40,"tag":103,"props":1689,"children":1690},{},[1691],{"type":46,"value":1509},{"type":40,"tag":103,"props":1693,"children":1694},{"class":105,"line":545},[1695],{"type":40,"tag":103,"props":1696,"children":1697},{},[1698],{"type":46,"value":1517},{"type":40,"tag":103,"props":1700,"children":1701},{"class":105,"line":554},[1702],{"type":40,"tag":103,"props":1703,"children":1704},{},[1705],{"type":46,"value":1525},{"type":40,"tag":103,"props":1707,"children":1708},{"class":105,"line":563},[1709],{"type":40,"tag":103,"props":1710,"children":1711},{},[1712],{"type":46,"value":1713},"    let inner = connection.inner().clone();\n",{"type":40,"tag":103,"props":1715,"children":1716},{"class":105,"line":572},[1717],{"type":40,"tag":103,"props":1718,"children":1719},{"emptyLinePlaceholder":504},[1720],{"type":46,"value":507},{"type":40,"tag":103,"props":1722,"children":1723},{"class":105,"line":580},[1724],{"type":40,"tag":103,"props":1725,"children":1726},{},[1727],{"type":46,"value":1728},"    inner.on_open(|| println!(\"connected\")).await;\n",{"type":40,"tag":103,"props":1730,"children":1731},{"class":105,"line":23},[1732],{"type":40,"tag":103,"props":1733,"children":1734},{},[1735],{"type":46,"value":1736},"    inner.on_close(|| println!(\"disconnected\")).await;\n",{"type":40,"tag":103,"props":1738,"children":1739},{"class":105,"line":776},[1740],{"type":40,"tag":103,"props":1741,"children":1742},{},[1743],{"type":46,"value":1744},"    inner.on_error(|message| eprintln!(\"error: {message}\")).await;\n",{"type":40,"tag":103,"props":1746,"children":1747},{"class":105,"line":785},[1748],{"type":40,"tag":103,"props":1749,"children":1750},{},[1751],{"type":46,"value":1752},"    inner\n",{"type":40,"tag":103,"props":1754,"children":1755},{"class":105,"line":794},[1756],{"type":40,"tag":103,"props":1757,"children":1758},{},[1759],{"type":46,"value":1760},"        .on_status_change(|status| println!(\"status: {status:?}\"))\n",{"type":40,"tag":103,"props":1762,"children":1763},{"class":105,"line":803},[1764],{"type":40,"tag":103,"props":1765,"children":1766},{},[1767],{"type":46,"value":800},{"type":40,"tag":103,"props":1769,"children":1770},{"class":105,"line":812},[1771],{"type":40,"tag":103,"props":1772,"children":1773},{"emptyLinePlaceholder":504},[1774],{"type":46,"value":507},{"type":40,"tag":103,"props":1776,"children":1777},{"class":105,"line":820},[1778],{"type":40,"tag":103,"props":1779,"children":1780},{},[1781],{"type":46,"value":1782},"    println!(\"current status: {:?}\", inner.conn_status());\n",{"type":40,"tag":103,"props":1784,"children":1785},{"class":105,"line":829},[1786],{"type":40,"tag":103,"props":1787,"children":1788},{"emptyLinePlaceholder":504},[1789],{"type":46,"value":507},{"type":40,"tag":103,"props":1791,"children":1792},{"class":105,"line":837},[1793],{"type":40,"tag":103,"props":1794,"children":1795},{},[1796],{"type":46,"value":826},{"type":40,"tag":103,"props":1798,"children":1799},{"class":105,"line":1052},[1800],{"type":40,"tag":103,"props":1801,"children":1802},{},[1803],{"type":46,"value":586},{"type":40,"tag":103,"props":1805,"children":1806},{"class":105,"line":1061},[1807],{"type":40,"tag":103,"props":1808,"children":1809},{},[1810],{"type":46,"value":594},{"type":40,"tag":49,"props":1812,"children":1813},{},[1814,1820,1822,1828,1830,1836,1837,1843,1845,1851,1853,1859],{"type":40,"tag":55,"props":1815,"children":1817},{"className":1816},[],[1818],{"type":46,"value":1819},"ConnectionStatus",{"type":46,"value":1821}," is one of ",{"type":40,"tag":55,"props":1823,"children":1825},{"className":1824},[],[1826],{"type":46,"value":1827},"Idle",{"type":46,"value":1829},", ",{"type":40,"tag":55,"props":1831,"children":1833},{"className":1832},[],[1834],{"type":46,"value":1835},"Connecting",{"type":46,"value":1829},{"type":40,"tag":55,"props":1838,"children":1840},{"className":1839},[],[1841],{"type":46,"value":1842},"Connected",{"type":46,"value":1844},", or ",{"type":40,"tag":55,"props":1846,"children":1848},{"className":1847},[],[1849],{"type":46,"value":1850},"Disconnected",{"type":46,"value":1852},". Connections reconnect automatically with backoff until you call ",{"type":40,"tag":55,"props":1854,"children":1856},{"className":1855},[],[1857],{"type":46,"value":1858},"disconnect",{"type":46,"value":62},{"type":40,"tag":64,"props":1861,"children":1863},{"id":1862},"low-level-http-websocket",[1864],{"type":46,"value":1865},"Low-Level HTTP & WebSocket",{"type":40,"tag":49,"props":1867,"children":1868},{},[1869,1871,1877,1879,1885,1887,1893,1895,1901,1903,1909,1911,1917,1918,1924],{"type":46,"value":1870},"For actors that implement ",{"type":40,"tag":55,"props":1872,"children":1874},{"className":1873},[],[1875],{"type":46,"value":1876},"on_request",{"type":46,"value":1878}," or ",{"type":40,"tag":55,"props":1880,"children":1882},{"className":1881},[],[1883],{"type":46,"value":1884},"on_websocket",{"type":46,"value":1886},", call them directly on the untyped handle (",{"type":40,"tag":55,"props":1888,"children":1890},{"className":1889},[],[1891],{"type":46,"value":1892},"handle.inner()",{"type":46,"value":1894},"). ",{"type":40,"tag":55,"props":1896,"children":1898},{"className":1897},[],[1899],{"type":46,"value":1900},"fetch",{"type":46,"value":1902}," returns a ",{"type":40,"tag":55,"props":1904,"children":1906},{"className":1905},[],[1907],{"type":46,"value":1908},"reqwest::Response",{"type":46,"value":1910},", and ",{"type":40,"tag":55,"props":1912,"children":1914},{"className":1913},[],[1915],{"type":46,"value":1916},"web_socket",{"type":46,"value":1902},{"type":40,"tag":55,"props":1919,"children":1921},{"className":1920},[],[1922],{"type":46,"value":1923},"tokio_tungstenite",{"type":46,"value":1925}," stream. This example also needs a few extra crates:",{"type":40,"tag":92,"props":1927,"children":1929},{"className":94,"code":1928,"language":96,"meta":97,"style":97},"cargo add futures-util tokio-tungstenite\ncargo add reqwest --features json\n",[1930],{"type":40,"tag":55,"props":1931,"children":1932},{"__ignoreMap":97},[1933,1954],{"type":40,"tag":103,"props":1934,"children":1935},{"class":105,"line":106},[1936,1940,1944,1949],{"type":40,"tag":103,"props":1937,"children":1938},{"style":110},[1939],{"type":46,"value":113},{"type":40,"tag":103,"props":1941,"children":1942},{"style":116},[1943],{"type":46,"value":119},{"type":40,"tag":103,"props":1945,"children":1946},{"style":116},[1947],{"type":46,"value":1948}," futures-util",{"type":40,"tag":103,"props":1950,"children":1951},{"style":116},[1952],{"type":46,"value":1953}," tokio-tungstenite\n",{"type":40,"tag":103,"props":1955,"children":1956},{"class":105,"line":137},[1957,1961,1965,1970,1974],{"type":40,"tag":103,"props":1958,"children":1959},{"style":110},[1960],{"type":46,"value":113},{"type":40,"tag":103,"props":1962,"children":1963},{"style":116},[1964],{"type":46,"value":119},{"type":40,"tag":103,"props":1966,"children":1967},{"style":116},[1968],{"type":46,"value":1969}," reqwest",{"type":40,"tag":103,"props":1971,"children":1972},{"style":116},[1973],{"type":46,"value":156},{"type":40,"tag":103,"props":1975,"children":1976},{"style":116},[1977],{"type":46,"value":1978}," json\n",{"type":40,"tag":92,"props":1980,"children":1982},{"className":441,"code":1981,"language":19,"meta":443,"style":97},"use counter::Counter;\nuse futures_util::{SinkExt, StreamExt};\nuse reqwest::{header::HeaderMap, Method};\nuse rivetkit::{\n    client::{Client, ClientConfig},\n    prelude::*,\n    TypedClientExt,\n};\nuse tokio_tungstenite::tungstenite::Message;\n\n#[tokio::main]\nasync fn main() -> Result\u003C()> {\n    let client = Client::new(ClientConfig::new(\"http:\u002F\u002Flocalhost:6420\").namespace(\"default\"));\n    let handle = client.get_or_create_typed_default::\u003CCounter>(\"counter\", [\"general\"])?;\n\n    \u002F\u002F Raw HTTP request\n    let response = handle\n        .inner()\n        .fetch(\"history\", Method::GET, HeaderMap::new(), None)\n        .await?;\n    let history: Vec\u003CString> = response.json().await?;\n    println!(\"history: {history:?}\");\n\n    \u002F\u002F Raw WebSocket connection\n    let mut ws = handle.inner().web_socket(\"stream\", None).await?;\n    ws.send(Message::text(\"hello\")).await?;\n    if let Some(message) = ws.next().await {\n        println!(\"received: {:?}\", message?);\n    }\n\n    Ok(())\n}\n",[1983],{"type":40,"tag":55,"props":1984,"children":1985},{"__ignoreMap":97},[1986,1993,2001,2009,2016,2023,2030,2037,2044,2052,2059,2066,2073,2080,2088,2095,2103,2111,2119,2127,2135,2143,2151,2158,2166,2174,2182,2190,2198,2206,2213,2220],{"type":40,"tag":103,"props":1987,"children":1988},{"class":105,"line":106},[1989],{"type":40,"tag":103,"props":1990,"children":1991},{},[1992],{"type":46,"value":868},{"type":40,"tag":103,"props":1994,"children":1995},{"class":105,"line":137},[1996],{"type":40,"tag":103,"props":1997,"children":1998},{},[1999],{"type":46,"value":2000},"use futures_util::{SinkExt, StreamExt};\n",{"type":40,"tag":103,"props":2002,"children":2003},{"class":105,"line":164},[2004],{"type":40,"tag":103,"props":2005,"children":2006},{},[2007],{"type":46,"value":2008},"use reqwest::{header::HeaderMap, Method};\n",{"type":40,"tag":103,"props":2010,"children":2011},{"class":105,"line":474},[2012],{"type":40,"tag":103,"props":2013,"children":2014},{},[2015],{"type":46,"value":463},{"type":40,"tag":103,"props":2017,"children":2018},{"class":105,"line":483},[2019],{"type":40,"tag":103,"props":2020,"children":2021},{},[2022],{"type":46,"value":471},{"type":40,"tag":103,"props":2024,"children":2025},{"class":105,"line":492},[2026],{"type":40,"tag":103,"props":2027,"children":2028},{},[2029],{"type":46,"value":480},{"type":40,"tag":103,"props":2031,"children":2032},{"class":105,"line":27},[2033],{"type":40,"tag":103,"props":2034,"children":2035},{},[2036],{"type":46,"value":489},{"type":40,"tag":103,"props":2038,"children":2039},{"class":105,"line":510},[2040],{"type":40,"tag":103,"props":2041,"children":2042},{},[2043],{"type":46,"value":498},{"type":40,"tag":103,"props":2045,"children":2046},{"class":105,"line":519},[2047],{"type":40,"tag":103,"props":2048,"children":2049},{},[2050],{"type":46,"value":2051},"use tokio_tungstenite::tungstenite::Message;\n",{"type":40,"tag":103,"props":2053,"children":2054},{"class":105,"line":528},[2055],{"type":40,"tag":103,"props":2056,"children":2057},{"emptyLinePlaceholder":504},[2058],{"type":46,"value":507},{"type":40,"tag":103,"props":2060,"children":2061},{"class":105,"line":537},[2062],{"type":40,"tag":103,"props":2063,"children":2064},{},[2065],{"type":46,"value":516},{"type":40,"tag":103,"props":2067,"children":2068},{"class":105,"line":545},[2069],{"type":40,"tag":103,"props":2070,"children":2071},{},[2072],{"type":46,"value":525},{"type":40,"tag":103,"props":2074,"children":2075},{"class":105,"line":554},[2076],{"type":40,"tag":103,"props":2077,"children":2078},{},[2079],{"type":46,"value":534},{"type":40,"tag":103,"props":2081,"children":2082},{"class":105,"line":563},[2083],{"type":40,"tag":103,"props":2084,"children":2085},{},[2086],{"type":46,"value":2087},"    let handle = client.get_or_create_typed_default::\u003CCounter>(\"counter\", [\"general\"])?;\n",{"type":40,"tag":103,"props":2089,"children":2090},{"class":105,"line":572},[2091],{"type":40,"tag":103,"props":2092,"children":2093},{"emptyLinePlaceholder":504},[2094],{"type":46,"value":507},{"type":40,"tag":103,"props":2096,"children":2097},{"class":105,"line":580},[2098],{"type":40,"tag":103,"props":2099,"children":2100},{},[2101],{"type":46,"value":2102},"    \u002F\u002F Raw HTTP request\n",{"type":40,"tag":103,"props":2104,"children":2105},{"class":105,"line":23},[2106],{"type":40,"tag":103,"props":2107,"children":2108},{},[2109],{"type":46,"value":2110},"    let response = handle\n",{"type":40,"tag":103,"props":2112,"children":2113},{"class":105,"line":776},[2114],{"type":40,"tag":103,"props":2115,"children":2116},{},[2117],{"type":46,"value":2118},"        .inner()\n",{"type":40,"tag":103,"props":2120,"children":2121},{"class":105,"line":785},[2122],{"type":40,"tag":103,"props":2123,"children":2124},{},[2125],{"type":46,"value":2126},"        .fetch(\"history\", Method::GET, HeaderMap::new(), None)\n",{"type":40,"tag":103,"props":2128,"children":2129},{"class":105,"line":794},[2130],{"type":40,"tag":103,"props":2131,"children":2132},{},[2133],{"type":46,"value":2134},"        .await?;\n",{"type":40,"tag":103,"props":2136,"children":2137},{"class":105,"line":803},[2138],{"type":40,"tag":103,"props":2139,"children":2140},{},[2141],{"type":46,"value":2142},"    let history: Vec\u003CString> = response.json().await?;\n",{"type":40,"tag":103,"props":2144,"children":2145},{"class":105,"line":812},[2146],{"type":40,"tag":103,"props":2147,"children":2148},{},[2149],{"type":46,"value":2150},"    println!(\"history: {history:?}\");\n",{"type":40,"tag":103,"props":2152,"children":2153},{"class":105,"line":820},[2154],{"type":40,"tag":103,"props":2155,"children":2156},{"emptyLinePlaceholder":504},[2157],{"type":46,"value":507},{"type":40,"tag":103,"props":2159,"children":2160},{"class":105,"line":829},[2161],{"type":40,"tag":103,"props":2162,"children":2163},{},[2164],{"type":46,"value":2165},"    \u002F\u002F Raw WebSocket connection\n",{"type":40,"tag":103,"props":2167,"children":2168},{"class":105,"line":837},[2169],{"type":40,"tag":103,"props":2170,"children":2171},{},[2172],{"type":46,"value":2173},"    let mut ws = handle.inner().web_socket(\"stream\", None).await?;\n",{"type":40,"tag":103,"props":2175,"children":2176},{"class":105,"line":1052},[2177],{"type":40,"tag":103,"props":2178,"children":2179},{},[2180],{"type":46,"value":2181},"    ws.send(Message::text(\"hello\")).await?;\n",{"type":40,"tag":103,"props":2183,"children":2184},{"class":105,"line":1061},[2185],{"type":40,"tag":103,"props":2186,"children":2187},{},[2188],{"type":46,"value":2189},"    if let Some(message) = ws.next().await {\n",{"type":40,"tag":103,"props":2191,"children":2192},{"class":105,"line":1070},[2193],{"type":40,"tag":103,"props":2194,"children":2195},{},[2196],{"type":46,"value":2197},"        println!(\"received: {:?}\", message?);\n",{"type":40,"tag":103,"props":2199,"children":2200},{"class":105,"line":1078},[2201],{"type":40,"tag":103,"props":2202,"children":2203},{},[2204],{"type":46,"value":2205},"    }\n",{"type":40,"tag":103,"props":2207,"children":2208},{"class":105,"line":1087},[2209],{"type":40,"tag":103,"props":2210,"children":2211},{"emptyLinePlaceholder":504},[2212],{"type":46,"value":507},{"type":40,"tag":103,"props":2214,"children":2215},{"class":105,"line":1096},[2216],{"type":40,"tag":103,"props":2217,"children":2218},{},[2219],{"type":46,"value":586},{"type":40,"tag":103,"props":2221,"children":2222},{"class":105,"line":1104},[2223],{"type":40,"tag":103,"props":2224,"children":2225},{},[2226],{"type":46,"value":594},{"type":40,"tag":64,"props":2228,"children":2230},{"id":2229},"calling-from-backend",[2231],{"type":46,"value":2232},"Calling from Backend",{"type":40,"tag":49,"props":2234,"children":2235},{},[2236,2238,2244],{"type":46,"value":2237},"The client is a normal Tokio type, so you can hold it in your backend (Axum, Actix, etc.) and call actors from request handlers. The client is ",{"type":40,"tag":55,"props":2239,"children":2241},{"className":2240},[],[2242],{"type":46,"value":2243},"Clone",{"type":46,"value":2245}," and cheap to share:",{"type":40,"tag":92,"props":2247,"children":2249},{"className":441,"code":2248,"language":19,"meta":443,"style":97},"use counter::{Counter, Increment};\nuse rivetkit::{\n    client::{Client, ClientConfig},\n    prelude::*,\n    TypedClientExt,\n};\n\nasync fn increment(client: Client) -> Result\u003Ci64> {\n    let counter = client.get_or_create_typed_default::\u003CCounter>(\"counter\", [\"server-counter\"])?;\n    let count = counter.send(Increment { amount: 1 }).await?;\n    Ok(count)\n}\n",[2250],{"type":40,"tag":55,"props":2251,"children":2252},{"__ignoreMap":97},[2253,2260,2267,2274,2281,2288,2295,2302,2310,2318,2325,2333],{"type":40,"tag":103,"props":2254,"children":2255},{"class":105,"line":106},[2256],{"type":40,"tag":103,"props":2257,"children":2258},{},[2259],{"type":46,"value":455},{"type":40,"tag":103,"props":2261,"children":2262},{"class":105,"line":137},[2263],{"type":40,"tag":103,"props":2264,"children":2265},{},[2266],{"type":46,"value":463},{"type":40,"tag":103,"props":2268,"children":2269},{"class":105,"line":164},[2270],{"type":40,"tag":103,"props":2271,"children":2272},{},[2273],{"type":46,"value":471},{"type":40,"tag":103,"props":2275,"children":2276},{"class":105,"line":474},[2277],{"type":40,"tag":103,"props":2278,"children":2279},{},[2280],{"type":46,"value":480},{"type":40,"tag":103,"props":2282,"children":2283},{"class":105,"line":483},[2284],{"type":40,"tag":103,"props":2285,"children":2286},{},[2287],{"type":46,"value":489},{"type":40,"tag":103,"props":2289,"children":2290},{"class":105,"line":492},[2291],{"type":40,"tag":103,"props":2292,"children":2293},{},[2294],{"type":46,"value":498},{"type":40,"tag":103,"props":2296,"children":2297},{"class":105,"line":27},[2298],{"type":40,"tag":103,"props":2299,"children":2300},{"emptyLinePlaceholder":504},[2301],{"type":46,"value":507},{"type":40,"tag":103,"props":2303,"children":2304},{"class":105,"line":510},[2305],{"type":40,"tag":103,"props":2306,"children":2307},{},[2308],{"type":46,"value":2309},"async fn increment(client: Client) -> Result\u003Ci64> {\n",{"type":40,"tag":103,"props":2311,"children":2312},{"class":105,"line":519},[2313],{"type":40,"tag":103,"props":2314,"children":2315},{},[2316],{"type":46,"value":2317},"    let counter = client.get_or_create_typed_default::\u003CCounter>(\"counter\", [\"server-counter\"])?;\n",{"type":40,"tag":103,"props":2319,"children":2320},{"class":105,"line":528},[2321],{"type":40,"tag":103,"props":2322,"children":2323},{},[2324],{"type":46,"value":560},{"type":40,"tag":103,"props":2326,"children":2327},{"class":105,"line":537},[2328],{"type":40,"tag":103,"props":2329,"children":2330},{},[2331],{"type":46,"value":2332},"    Ok(count)\n",{"type":40,"tag":103,"props":2334,"children":2335},{"class":105,"line":545},[2336],{"type":40,"tag":103,"props":2337,"children":2338},{},[2339],{"type":46,"value":594},{"type":40,"tag":64,"props":2341,"children":2343},{"id":2342},"error-handling",[2344],{"type":46,"value":2345},"Error Handling",{"type":40,"tag":49,"props":2347,"children":2348},{},[2349,2351,2356,2358,2364],{"type":46,"value":2350},"Action and connection calls return ",{"type":40,"tag":55,"props":2352,"children":2354},{"className":2353},[],[2355],{"type":46,"value":228},{"type":46,"value":2357},". Actor-side errors surface as an ",{"type":40,"tag":55,"props":2359,"children":2361},{"className":2360},[],[2362],{"type":46,"value":2363},"anyhow::Error",{"type":46,"value":2365}," carrying the error group, code, message, and metadata:",{"type":40,"tag":92,"props":2367,"children":2369},{"className":441,"code":2368,"language":19,"meta":443,"style":97},"use counter::{Counter, Increment};\nuse rivetkit::{\n    client::{Client, ClientConfig},\n    prelude::*,\n    TypedClientExt,\n};\n\n#[tokio::main]\nasync fn main() -> Result\u003C()> {\n    let client = Client::new(ClientConfig::new(\"http:\u002F\u002Flocalhost:6420\").namespace(\"default\"));\n    let counter = client.get_or_create_typed_default::\u003CCounter>(\"counter\", [\"my-counter\"])?;\n\n    match counter.send(Increment { amount: 1 }).await {\n        Ok(count) => println!(\"count: {count}\"),\n        Err(error) => eprintln!(\"action failed: {error:#}\"),\n    }\n\n    Ok(())\n}\n",[2370],{"type":40,"tag":55,"props":2371,"children":2372},{"__ignoreMap":97},[2373,2380,2387,2394,2401,2408,2415,2422,2429,2436,2443,2450,2457,2465,2473,2481,2488,2495,2502],{"type":40,"tag":103,"props":2374,"children":2375},{"class":105,"line":106},[2376],{"type":40,"tag":103,"props":2377,"children":2378},{},[2379],{"type":46,"value":455},{"type":40,"tag":103,"props":2381,"children":2382},{"class":105,"line":137},[2383],{"type":40,"tag":103,"props":2384,"children":2385},{},[2386],{"type":46,"value":463},{"type":40,"tag":103,"props":2388,"children":2389},{"class":105,"line":164},[2390],{"type":40,"tag":103,"props":2391,"children":2392},{},[2393],{"type":46,"value":471},{"type":40,"tag":103,"props":2395,"children":2396},{"class":105,"line":474},[2397],{"type":40,"tag":103,"props":2398,"children":2399},{},[2400],{"type":46,"value":480},{"type":40,"tag":103,"props":2402,"children":2403},{"class":105,"line":483},[2404],{"type":40,"tag":103,"props":2405,"children":2406},{},[2407],{"type":46,"value":489},{"type":40,"tag":103,"props":2409,"children":2410},{"class":105,"line":492},[2411],{"type":40,"tag":103,"props":2412,"children":2413},{},[2414],{"type":46,"value":498},{"type":40,"tag":103,"props":2416,"children":2417},{"class":105,"line":27},[2418],{"type":40,"tag":103,"props":2419,"children":2420},{"emptyLinePlaceholder":504},[2421],{"type":46,"value":507},{"type":40,"tag":103,"props":2423,"children":2424},{"class":105,"line":510},[2425],{"type":40,"tag":103,"props":2426,"children":2427},{},[2428],{"type":46,"value":516},{"type":40,"tag":103,"props":2430,"children":2431},{"class":105,"line":519},[2432],{"type":40,"tag":103,"props":2433,"children":2434},{},[2435],{"type":46,"value":525},{"type":40,"tag":103,"props":2437,"children":2438},{"class":105,"line":528},[2439],{"type":40,"tag":103,"props":2440,"children":2441},{},[2442],{"type":46,"value":534},{"type":40,"tag":103,"props":2444,"children":2445},{"class":105,"line":537},[2446],{"type":40,"tag":103,"props":2447,"children":2448},{},[2449],{"type":46,"value":551},{"type":40,"tag":103,"props":2451,"children":2452},{"class":105,"line":545},[2453],{"type":40,"tag":103,"props":2454,"children":2455},{"emptyLinePlaceholder":504},[2456],{"type":46,"value":507},{"type":40,"tag":103,"props":2458,"children":2459},{"class":105,"line":554},[2460],{"type":40,"tag":103,"props":2461,"children":2462},{},[2463],{"type":46,"value":2464},"    match counter.send(Increment { amount: 1 }).await {\n",{"type":40,"tag":103,"props":2466,"children":2467},{"class":105,"line":563},[2468],{"type":40,"tag":103,"props":2469,"children":2470},{},[2471],{"type":46,"value":2472},"        Ok(count) => println!(\"count: {count}\"),\n",{"type":40,"tag":103,"props":2474,"children":2475},{"class":105,"line":572},[2476],{"type":40,"tag":103,"props":2477,"children":2478},{},[2479],{"type":46,"value":2480},"        Err(error) => eprintln!(\"action failed: {error:#}\"),\n",{"type":40,"tag":103,"props":2482,"children":2483},{"class":105,"line":580},[2484],{"type":40,"tag":103,"props":2485,"children":2486},{},[2487],{"type":46,"value":2205},{"type":40,"tag":103,"props":2489,"children":2490},{"class":105,"line":23},[2491],{"type":40,"tag":103,"props":2492,"children":2493},{"emptyLinePlaceholder":504},[2494],{"type":46,"value":507},{"type":40,"tag":103,"props":2496,"children":2497},{"class":105,"line":776},[2498],{"type":40,"tag":103,"props":2499,"children":2500},{},[2501],{"type":46,"value":586},{"type":40,"tag":103,"props":2503,"children":2504},{"class":105,"line":785},[2505],{"type":40,"tag":103,"props":2506,"children":2507},{},[2508],{"type":46,"value":594},{"type":40,"tag":64,"props":2510,"children":2512},{"id":2511},"concepts",[2513],{"type":46,"value":2514},"Concepts",{"type":40,"tag":2516,"props":2517,"children":2519},"h3",{"id":2518},"keys",[2520],{"type":46,"value":2521},"Keys",{"type":40,"tag":49,"props":2523,"children":2524},{},[2525],{"type":46,"value":2526},"Keys uniquely identify actor instances. Use compound keys (arrays) for hierarchical addressing:",{"type":40,"tag":92,"props":2528,"children":2530},{"className":441,"code":2529,"language":19,"meta":443,"style":97},"use counter::Counter;\nuse rivetkit::{\n    client::{Client, ClientConfig},\n    prelude::*,\n    TypedClientExt,\n};\n\n#[tokio::main]\nasync fn main() -> Result\u003C()> {\n    let client = Client::new(ClientConfig::new(\"http:\u002F\u002Flocalhost:6420\").namespace(\"default\"));\n\n    \u002F\u002F Compound key: [org, room]\n    let room = client.get_or_create_typed_default::\u003CCounter>(\"counter\", [\"org-acme\", \"general\"])?;\n    let actor_id = room.inner().resolve().await?;\n    println!(\"Actor ID: {actor_id}\");\n\n    Ok(())\n}\n",[2531],{"type":40,"tag":55,"props":2532,"children":2533},{"__ignoreMap":97},[2534,2541,2548,2555,2562,2569,2576,2583,2590,2597,2604,2611,2619,2627,2635,2643,2650,2657],{"type":40,"tag":103,"props":2535,"children":2536},{"class":105,"line":106},[2537],{"type":40,"tag":103,"props":2538,"children":2539},{},[2540],{"type":46,"value":868},{"type":40,"tag":103,"props":2542,"children":2543},{"class":105,"line":137},[2544],{"type":40,"tag":103,"props":2545,"children":2546},{},[2547],{"type":46,"value":463},{"type":40,"tag":103,"props":2549,"children":2550},{"class":105,"line":164},[2551],{"type":40,"tag":103,"props":2552,"children":2553},{},[2554],{"type":46,"value":471},{"type":40,"tag":103,"props":2556,"children":2557},{"class":105,"line":474},[2558],{"type":40,"tag":103,"props":2559,"children":2560},{},[2561],{"type":46,"value":480},{"type":40,"tag":103,"props":2563,"children":2564},{"class":105,"line":483},[2565],{"type":40,"tag":103,"props":2566,"children":2567},{},[2568],{"type":46,"value":489},{"type":40,"tag":103,"props":2570,"children":2571},{"class":105,"line":492},[2572],{"type":40,"tag":103,"props":2573,"children":2574},{},[2575],{"type":46,"value":498},{"type":40,"tag":103,"props":2577,"children":2578},{"class":105,"line":27},[2579],{"type":40,"tag":103,"props":2580,"children":2581},{"emptyLinePlaceholder":504},[2582],{"type":46,"value":507},{"type":40,"tag":103,"props":2584,"children":2585},{"class":105,"line":510},[2586],{"type":40,"tag":103,"props":2587,"children":2588},{},[2589],{"type":46,"value":516},{"type":40,"tag":103,"props":2591,"children":2592},{"class":105,"line":519},[2593],{"type":40,"tag":103,"props":2594,"children":2595},{},[2596],{"type":46,"value":525},{"type":40,"tag":103,"props":2598,"children":2599},{"class":105,"line":528},[2600],{"type":40,"tag":103,"props":2601,"children":2602},{},[2603],{"type":46,"value":534},{"type":40,"tag":103,"props":2605,"children":2606},{"class":105,"line":537},[2607],{"type":40,"tag":103,"props":2608,"children":2609},{"emptyLinePlaceholder":504},[2610],{"type":46,"value":507},{"type":40,"tag":103,"props":2612,"children":2613},{"class":105,"line":545},[2614],{"type":40,"tag":103,"props":2615,"children":2616},{},[2617],{"type":46,"value":2618},"    \u002F\u002F Compound key: [org, room]\n",{"type":40,"tag":103,"props":2620,"children":2621},{"class":105,"line":554},[2622],{"type":40,"tag":103,"props":2623,"children":2624},{},[2625],{"type":46,"value":2626},"    let room = client.get_or_create_typed_default::\u003CCounter>(\"counter\", [\"org-acme\", \"general\"])?;\n",{"type":40,"tag":103,"props":2628,"children":2629},{"class":105,"line":563},[2630],{"type":40,"tag":103,"props":2631,"children":2632},{},[2633],{"type":46,"value":2634},"    let actor_id = room.inner().resolve().await?;\n",{"type":40,"tag":103,"props":2636,"children":2637},{"class":105,"line":572},[2638],{"type":40,"tag":103,"props":2639,"children":2640},{},[2641],{"type":46,"value":2642},"    println!(\"Actor ID: {actor_id}\");\n",{"type":40,"tag":103,"props":2644,"children":2645},{"class":105,"line":580},[2646],{"type":40,"tag":103,"props":2647,"children":2648},{"emptyLinePlaceholder":504},[2649],{"type":46,"value":507},{"type":40,"tag":103,"props":2651,"children":2652},{"class":105,"line":23},[2653],{"type":40,"tag":103,"props":2654,"children":2655},{},[2656],{"type":46,"value":586},{"type":40,"tag":103,"props":2658,"children":2659},{"class":105,"line":776},[2660],{"type":40,"tag":103,"props":2661,"children":2662},{},[2663],{"type":46,"value":594},{"type":40,"tag":49,"props":2665,"children":2666},{},[2667,2669,2675,2676,2682,2684,2690,2692,2698,2700,2706],{"type":46,"value":2668},"Keys accept arrays of ",{"type":40,"tag":55,"props":2670,"children":2672},{"className":2671},[],[2673],{"type":46,"value":2674},"&str",{"type":46,"value":1878},{"type":40,"tag":55,"props":2677,"children":2679},{"className":2678},[],[2680],{"type":46,"value":2681},"String",{"type":46,"value":2683}," (",{"type":40,"tag":55,"props":2685,"children":2687},{"className":2686},[],[2688],{"type":46,"value":2689},"[\"org-acme\", \"general\"]",{"type":46,"value":2691},"). Don't build keys with string interpolation like ",{"type":40,"tag":55,"props":2693,"children":2695},{"className":2694},[],[2696],{"type":46,"value":2697},"format!(\"org:{user_id}\")",{"type":46,"value":2699}," when ",{"type":40,"tag":55,"props":2701,"children":2703},{"className":2702},[],[2704],{"type":46,"value":2705},"user_id",{"type":46,"value":2707}," contains user data. Use arrays instead to prevent key injection attacks.",{"type":40,"tag":2516,"props":2709,"children":2711},{"id":2710},"configuration",[2712],{"type":46,"value":2713},"Configuration",{"type":40,"tag":49,"props":2715,"children":2716},{},[2717,2723],{"type":40,"tag":55,"props":2718,"children":2720},{"className":2719},[],[2721],{"type":46,"value":2722},"ClientConfig::new(endpoint)",{"type":46,"value":2724}," is a builder. The endpoint is always required; there is no default. Common options:",{"type":40,"tag":92,"props":2726,"children":2728},{"className":441,"code":2727,"language":19,"meta":443,"style":97},"use rivetkit::client::ClientConfig;\n\nlet config = ClientConfig::new(\"http:\u002F\u002Flocalhost:6420\")\n    .namespace(\"default\")\n    .token(\"pk_...\")\n    .pool_name(\"my-pool\")\n    .header(\"x-custom\", \"value\");\n",[2729],{"type":40,"tag":55,"props":2730,"children":2731},{"__ignoreMap":97},[2732,2740,2747,2755,2763,2771,2779],{"type":40,"tag":103,"props":2733,"children":2734},{"class":105,"line":106},[2735],{"type":40,"tag":103,"props":2736,"children":2737},{},[2738],{"type":46,"value":2739},"use rivetkit::client::ClientConfig;\n",{"type":40,"tag":103,"props":2741,"children":2742},{"class":105,"line":137},[2743],{"type":40,"tag":103,"props":2744,"children":2745},{"emptyLinePlaceholder":504},[2746],{"type":46,"value":507},{"type":40,"tag":103,"props":2748,"children":2749},{"class":105,"line":164},[2750],{"type":40,"tag":103,"props":2751,"children":2752},{},[2753],{"type":46,"value":2754},"let config = ClientConfig::new(\"http:\u002F\u002Flocalhost:6420\")\n",{"type":40,"tag":103,"props":2756,"children":2757},{"class":105,"line":474},[2758],{"type":40,"tag":103,"props":2759,"children":2760},{},[2761],{"type":46,"value":2762},"    .namespace(\"default\")\n",{"type":40,"tag":103,"props":2764,"children":2765},{"class":105,"line":483},[2766],{"type":40,"tag":103,"props":2767,"children":2768},{},[2769],{"type":46,"value":2770},"    .token(\"pk_...\")\n",{"type":40,"tag":103,"props":2772,"children":2773},{"class":105,"line":492},[2774],{"type":40,"tag":103,"props":2775,"children":2776},{},[2777],{"type":46,"value":2778},"    .pool_name(\"my-pool\")\n",{"type":40,"tag":103,"props":2780,"children":2781},{"class":105,"line":27},[2782],{"type":40,"tag":103,"props":2783,"children":2784},{},[2785],{"type":46,"value":2786},"    .header(\"x-custom\", \"value\");\n",{"type":40,"tag":215,"props":2788,"children":2789},{},[2790,2801,2812,2823,2841],{"type":40,"tag":86,"props":2791,"children":2792},{},[2793,2799],{"type":40,"tag":55,"props":2794,"children":2796},{"className":2795},[],[2797],{"type":46,"value":2798},"namespace",{"type":46,"value":2800}," - target namespace (defaults to the engine's configured namespace).",{"type":40,"tag":86,"props":2802,"children":2803},{},[2804,2810],{"type":40,"tag":55,"props":2805,"children":2807},{"className":2806},[],[2808],{"type":46,"value":2809},"token",{"type":46,"value":2811}," - authentication token for the engine.",{"type":40,"tag":86,"props":2813,"children":2814},{},[2815,2821],{"type":40,"tag":55,"props":2816,"children":2818},{"className":2817},[],[2819],{"type":46,"value":2820},"pool_name",{"type":46,"value":2822}," - runner pool to target.",{"type":40,"tag":86,"props":2824,"children":2825},{},[2826,2832,2833,2839],{"type":40,"tag":55,"props":2827,"children":2829},{"className":2828},[],[2830],{"type":46,"value":2831},"header",{"type":46,"value":1163},{"type":40,"tag":55,"props":2834,"children":2836},{"className":2835},[],[2837],{"type":46,"value":2838},"headers",{"type":46,"value":2840}," - extra HTTP headers sent with each request.",{"type":40,"tag":86,"props":2842,"children":2843},{},[2844,2850],{"type":40,"tag":55,"props":2845,"children":2847},{"className":2846},[],[2848],{"type":46,"value":2849},"max_input_size",{"type":46,"value":2851}," - cap on encoded action input size.",{"type":40,"tag":49,"props":2853,"children":2854},{},[2855,2857,2863,2865,2871],{"type":46,"value":2856},"For serverless deployments, set the endpoint to your app's ",{"type":40,"tag":55,"props":2858,"children":2860},{"className":2859},[],[2861],{"type":46,"value":2862},"\u002Fapi\u002Frivet",{"type":46,"value":2864}," URL. See ",{"type":40,"tag":277,"props":2866,"children":2868},{"href":2867},"\u002Fdocs\u002Fgeneral\u002Fendpoints",[2869],{"type":46,"value":2870},"Endpoints",{"type":46,"value":2872}," for details.",{"type":40,"tag":64,"props":2874,"children":2876},{"id":2875},"api-reference",[2877],{"type":46,"value":2878},"API Reference",{"type":40,"tag":49,"props":2880,"children":2881},{},[2882,2884,2891],{"type":46,"value":2883},"See the full client API documentation on ",{"type":40,"tag":277,"props":2885,"children":2888},{"href":2886,"rel":2887},"https:\u002F\u002Fdocs.rs\u002Frivetkit-client\u002Flatest\u002Frivetkit_client\u002F",[281],[2889],{"type":46,"value":2890},"docs.rs\u002Frivetkit-client",{"type":46,"value":62},{"type":40,"tag":64,"props":2893,"children":2895},{"id":2894},"need-more-than-the-client",[2896],{"type":46,"value":2897},"Need More Than the Client?",{"type":40,"tag":49,"props":2899,"children":2900},{},[2901],{"type":46,"value":2902},"If you need more about Rivet Actors, registries, or server-side RivetKit, add the main skill:",{"type":40,"tag":92,"props":2904,"children":2908},{"className":2905,"code":2906,"language":2907,"meta":97,"style":97},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","npx skills add rivet-dev\u002Fskills\n","bash",[2909],{"type":40,"tag":55,"props":2910,"children":2911},{"__ignoreMap":97},[2912],{"type":40,"tag":103,"props":2913,"children":2914},{"class":105,"line":106},[2915,2920,2925,2929],{"type":40,"tag":103,"props":2916,"children":2917},{"style":110},[2918],{"type":46,"value":2919},"npx",{"type":40,"tag":103,"props":2921,"children":2922},{"style":116},[2923],{"type":46,"value":2924}," skills",{"type":40,"tag":103,"props":2926,"children":2927},{"style":116},[2928],{"type":46,"value":119},{"type":40,"tag":103,"props":2930,"children":2931},{"style":116},[2932],{"type":46,"value":2933}," rivet-dev\u002Fskills\n",{"type":40,"tag":49,"props":2935,"children":2936},{},[2937,2939,2944],{"type":46,"value":2938},"Then use the ",{"type":40,"tag":55,"props":2940,"children":2942},{"className":2941},[],[2943],{"type":46,"value":266},{"type":46,"value":2945}," skill for backend guidance.",{"type":40,"tag":2947,"props":2948,"children":2949},"style",{},[2950],{"type":46,"value":2951},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":2953,"total":23},[2954,2975,2993,3012,3028,3044,3061,3079,3097,3112,3128,3144],{"slug":2955,"name":2955,"fn":2956,"description":2957,"org":2958,"tags":2959,"stars":23,"repoUrl":24,"updatedAt":2974},"ai-agent","build AI agent backends with Rivet","Build an AI agent backend with persistent memory: one Rivet Actor per conversation, queued message handling, and streaming LLM responses as realtime events.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2960,2963,2964,2967,2970,2973],{"name":2961,"slug":2962,"type":16},"Agents","agents",{"name":14,"slug":15,"type":16},{"name":2965,"slug":2966,"type":16},"LLM","llm",{"name":2968,"slug":2969,"type":16},"Memory","memory",{"name":2971,"slug":2972,"type":16},"Real-time","real-time",{"name":9,"slug":8,"type":16},"2026-07-21T05:37:45.411803",{"slug":2976,"name":2976,"fn":2977,"description":2978,"org":2979,"tags":2980,"stars":23,"repoUrl":24,"updatedAt":2992},"ai-agent-workspace","create persistent workspaces for AI agents","Give every AI agent its own computer: a persistent workspace with a filesystem, processes, shells, networking, and agent sessions on a lightweight in-process OS.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2981,2982,2985,2988,2989],{"name":2961,"slug":2962,"type":16},{"name":2983,"slug":2984,"type":16},"File Storage","file-storage",{"name":2986,"slug":2987,"type":16},"Infrastructure","infrastructure",{"name":9,"slug":8,"type":16},{"name":2990,"slug":2991,"type":16},"Sandboxing","sandboxing","2026-06-14T08:06:57.274844",{"slug":2994,"name":2994,"fn":2995,"description":2996,"org":2997,"tags":2998,"stars":23,"repoUrl":24,"updatedAt":3011},"chat-room","build realtime chat rooms with Rivet","Build a realtime chat room backend with Rivet Actors: one actor per room, SQLite-backed message history, and WebSocket broadcast to every connected client.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2999,3000,3003,3004,3005,3008],{"name":14,"slug":15,"type":16},{"name":3001,"slug":3002,"type":16},"Messaging","messaging",{"name":2971,"slug":2972,"type":16},{"name":9,"slug":8,"type":16},{"name":3006,"slug":3007,"type":16},"SQL","sql",{"name":3009,"slug":3010,"type":16},"WebSockets","websockets","2026-07-21T05:37:48.403494",{"slug":3013,"name":3013,"fn":3014,"description":3015,"org":3016,"tags":3017,"stars":23,"repoUrl":24,"updatedAt":3027},"collaborative-text-editor","build collaborative text editors with Rivet","Build a collaborative text editor backend with Yjs CRDTs and Rivet Actors: per-document actors relay sync and awareness updates and persist snapshots.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3018,3019,3022,3025,3026],{"name":14,"slug":15,"type":16},{"name":3020,"slug":3021,"type":16},"Collaboration","collaboration",{"name":3023,"slug":3024,"type":16},"Documents","documents",{"name":2971,"slug":2972,"type":16},{"name":9,"slug":8,"type":16},"2026-07-21T05:37:49.412829",{"slug":3029,"name":3029,"fn":3030,"description":3031,"org":3032,"tags":3033,"stars":23,"repoUrl":24,"updatedAt":3043},"cron-jobs","schedule durable cron jobs with Rivet","Patterns for durable one-shot, calendar, and fixed-interval work on Rivet Actors.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3034,3037,3038,3039,3040],{"name":3035,"slug":3036,"type":16},"Automation","automation",{"name":14,"slug":15,"type":16},{"name":2986,"slug":2987,"type":16},{"name":9,"slug":8,"type":16},{"name":3041,"slug":3042,"type":16},"Scheduling","scheduling","2026-07-21T05:37:43.395911",{"slug":3045,"name":3045,"fn":3046,"description":3047,"org":3048,"tags":3049,"stars":23,"repoUrl":24,"updatedAt":3060},"live-cursors","implement live cursors and multiplayer presence","Live cursors and multiplayer presence with Rivet Actors: per-connection cursor state, realtime updates over events or raw WebSockets, and throttling.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3050,3051,3054,3055,3056,3059],{"name":3020,"slug":3021,"type":16},{"name":3052,"slug":3053,"type":16},"Frontend","frontend",{"name":2971,"slug":2972,"type":16},{"name":9,"slug":8,"type":16},{"name":3057,"slug":3058,"type":16},"UX Design","ux-design",{"name":3009,"slug":3010,"type":16},"2026-07-21T05:37:47.391088",{"slug":3062,"name":3062,"fn":3063,"description":3064,"org":3065,"tags":3066,"stars":23,"repoUrl":24,"updatedAt":3078},"multiplayer-game","build multiplayer games with Rivet","Pragmatic patterns for building multiplayer games: matchmaking, tick loops, realtime state, interest management, and validation.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3067,3070,3073,3076,3077],{"name":3068,"slug":3069,"type":16},"Architecture","architecture",{"name":3071,"slug":3072,"type":16},"Engineering","engineering",{"name":3074,"slug":3075,"type":16},"Game Development","game-development",{"name":2971,"slug":2972,"type":16},{"name":9,"slug":8,"type":16},"2026-07-21T05:37:44.627991",{"slug":3080,"name":3080,"fn":3081,"description":3082,"org":3083,"tags":3084,"stars":23,"repoUrl":24,"updatedAt":3096},"per-tenant-database","implement multi-tenant data isolation with Rivet","Multi-tenant data isolation with one Rivet Actor per tenant: the actor key is the tenant id, so each tenant gets its own isolated dataset and migrations.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3085,3086,3089,3092,3095],{"name":3068,"slug":3069,"type":16},{"name":3087,"slug":3088,"type":16},"Database","database",{"name":3090,"slug":3091,"type":16},"Migration","migration",{"name":3093,"slug":3094,"type":16},"Multi-Tenant","multi-tenant",{"name":9,"slug":8,"type":16},"2026-07-21T05:37:46.414425",{"slug":266,"name":266,"fn":3098,"description":3099,"org":3100,"tags":3101,"stars":23,"repoUrl":24,"updatedAt":3111},"build and debug Rivet Actors","RivetKit backend and Rivet Actor runtime guidance. Use for building, modifying, debugging, or testing Rivet Actors, registries, serverless\u002Frunner modes, deployment, or actor-based workflows.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3102,3103,3104,3107,3110],{"name":2961,"slug":2962,"type":16},{"name":14,"slug":15,"type":16},{"name":3105,"slug":3106,"type":16},"Debugging","debugging",{"name":3108,"slug":3109,"type":16},"Deployment","deployment",{"name":9,"slug":8,"type":16},"2026-07-24T05:38:58.10133",{"slug":3113,"name":3113,"fn":3114,"description":3115,"org":3116,"tags":3117,"stars":23,"repoUrl":24,"updatedAt":3127},"rivetkit-client-javascript","use RivetKit JavaScript client","RivetKit JavaScript client guidance. Use for browser, Node.js, or Bun clients that connect to Rivet Actors with rivetkit\u002Fclient, create clients, call actions, or manage connections.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3118,3119,3120,3123,3124],{"name":14,"slug":15,"type":16},{"name":3052,"slug":3053,"type":16},{"name":3121,"slug":3122,"type":16},"JavaScript","javascript",{"name":9,"slug":8,"type":16},{"name":3125,"slug":3126,"type":16},"SDK","sdk","2026-07-30T05:31:37.725576",{"slug":3129,"name":3129,"fn":3130,"description":3131,"org":3132,"tags":3133,"stars":23,"repoUrl":24,"updatedAt":3143},"rivetkit-client-react","use RivetKit React client","RivetKit React client guidance. Use for React apps that connect to Rivet Actors with @rivetkit\u002Freact, create hooks with createRivetKit, or manage realtime state with useActor.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3134,3135,3138,3139,3140],{"name":3052,"slug":3053,"type":16},{"name":3136,"slug":3137,"type":16},"React","react",{"name":9,"slug":8,"type":16},{"name":3125,"slug":3126,"type":16},{"name":3141,"slug":3142,"type":16},"State Management","state-management","2026-07-30T05:31:36.618873",{"slug":4,"name":4,"fn":5,"description":6,"org":3145,"tags":3146,"stars":23,"repoUrl":24,"updatedAt":25},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3147,3148,3149],{"name":21,"slug":22,"type":16},{"name":14,"slug":15,"type":16},{"name":18,"slug":19,"type":16},{"items":3151,"total":580},[3152,3161,3169,3178,3186,3194,3203],{"slug":2955,"name":2955,"fn":2956,"description":2957,"org":3153,"tags":3154,"stars":23,"repoUrl":24,"updatedAt":2974},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3155,3156,3157,3158,3159,3160],{"name":2961,"slug":2962,"type":16},{"name":14,"slug":15,"type":16},{"name":2965,"slug":2966,"type":16},{"name":2968,"slug":2969,"type":16},{"name":2971,"slug":2972,"type":16},{"name":9,"slug":8,"type":16},{"slug":2976,"name":2976,"fn":2977,"description":2978,"org":3162,"tags":3163,"stars":23,"repoUrl":24,"updatedAt":2992},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3164,3165,3166,3167,3168],{"name":2961,"slug":2962,"type":16},{"name":2983,"slug":2984,"type":16},{"name":2986,"slug":2987,"type":16},{"name":9,"slug":8,"type":16},{"name":2990,"slug":2991,"type":16},{"slug":2994,"name":2994,"fn":2995,"description":2996,"org":3170,"tags":3171,"stars":23,"repoUrl":24,"updatedAt":3011},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3172,3173,3174,3175,3176,3177],{"name":14,"slug":15,"type":16},{"name":3001,"slug":3002,"type":16},{"name":2971,"slug":2972,"type":16},{"name":9,"slug":8,"type":16},{"name":3006,"slug":3007,"type":16},{"name":3009,"slug":3010,"type":16},{"slug":3013,"name":3013,"fn":3014,"description":3015,"org":3179,"tags":3180,"stars":23,"repoUrl":24,"updatedAt":3027},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3181,3182,3183,3184,3185],{"name":14,"slug":15,"type":16},{"name":3020,"slug":3021,"type":16},{"name":3023,"slug":3024,"type":16},{"name":2971,"slug":2972,"type":16},{"name":9,"slug":8,"type":16},{"slug":3029,"name":3029,"fn":3030,"description":3031,"org":3187,"tags":3188,"stars":23,"repoUrl":24,"updatedAt":3043},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3189,3190,3191,3192,3193],{"name":3035,"slug":3036,"type":16},{"name":14,"slug":15,"type":16},{"name":2986,"slug":2987,"type":16},{"name":9,"slug":8,"type":16},{"name":3041,"slug":3042,"type":16},{"slug":3045,"name":3045,"fn":3046,"description":3047,"org":3195,"tags":3196,"stars":23,"repoUrl":24,"updatedAt":3060},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3197,3198,3199,3200,3201,3202],{"name":3020,"slug":3021,"type":16},{"name":3052,"slug":3053,"type":16},{"name":2971,"slug":2972,"type":16},{"name":9,"slug":8,"type":16},{"name":3057,"slug":3058,"type":16},{"name":3009,"slug":3010,"type":16},{"slug":3062,"name":3062,"fn":3063,"description":3064,"org":3204,"tags":3205,"stars":23,"repoUrl":24,"updatedAt":3078},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3206,3207,3208,3209,3210],{"name":3068,"slug":3069,"type":16},{"name":3071,"slug":3072,"type":16},{"name":3074,"slug":3075,"type":16},{"name":2971,"slug":2972,"type":16},{"name":9,"slug":8,"type":16}]