{"id":19562713,"url":"https://github.com/jamsocket/stateroom","last_synced_at":"2025-04-05T16:08:15.051Z","repository":{"id":39899595,"uuid":"389361716","full_name":"jamsocket/stateroom","owner":"jamsocket","description":"A lightweight framework for building WebSocket-based application backends.","archived":false,"fork":false,"pushed_at":"2024-10-05T17:01:02.000Z","size":4484,"stargazers_count":143,"open_issues_count":0,"forks_count":5,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-28T10:54:35.902Z","etag":null,"topics":["rust","wasm","webassembly","websocket"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jamsocket.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-07-25T14:05:58.000Z","updated_at":"2025-02-13T23:26:40.000Z","dependencies_parsed_at":"2024-05-16T06:32:14.558Z","dependency_job_id":"e2699d73-69b2-45e1-aed9-c20743696ed8","html_url":"https://github.com/jamsocket/stateroom","commit_stats":{"total_commits":217,"total_committers":3,"mean_commits":72.33333333333333,"dds":0.05069124423963134,"last_synced_commit":"8ec288ec307565fb04d8c86d7af638e0e65a8f3e"},"previous_names":["jamsocket/jamsocket","jamsocket/stateroom"],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamsocket%2Fstateroom","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamsocket%2Fstateroom/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamsocket%2Fstateroom/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamsocket%2Fstateroom/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jamsocket","download_url":"https://codeload.github.com/jamsocket/stateroom/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247361690,"owners_count":20926643,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["rust","wasm","webassembly","websocket"],"created_at":"2024-11-11T05:15:27.292Z","updated_at":"2025-04-05T16:08:15.025Z","avatar_url":"https://github.com/jamsocket.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Stateroom\n\n[![crates.io](https://img.shields.io/crates/v/stateroom.svg)](https://crates.io/crates/stateroom)\n[![docs.rs](https://img.shields.io/badge/docs-release-brightgreen)](https://docs.rs/stateroom/0.1.0/stateroom/)\n[![wokflow state](https://github.com/drifting-in-space/stateroom/actions/workflows/test.yml/badge.svg)](https://github.com/drifting-in-space/stateroom/actions/workflows/test.yml)\n\nStateroom is a minimalist framework for building lightweight, single-threaded services that send and\nreceive messages through [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API).\n\nServices can either be native Rust code that runs in the server process, or be compiled into\n[WebAssembly](https://webassembly.org/) modules and loaded dynamically.\n\n## Usage\n\nTo create a Stateroom service, implement the `SimpleStateroomService` trait. There's only one function that you *must* implement, the constructor `new`.\n\nLet's implement a simple shared counter. Any connected client will be able to increment or decrement it by sending \n`increment` or `decrement` messages (other messages will be ignored). Whenever the value is changed, we'll broadcast it \nto every connected client.\n\n```rust\nuse stateroom_wasm::*;\n\n#[stateroom_wasm]\n#[derive(Default)]\nstruct EchoServer;\n\nimpl StateroomService for EchoServer {\n    fn connect(\u0026mut self, client_id: ClientId, ctx: \u0026impl StateroomContext) {\n        ctx.send_message(client_id, format!(\"User {:?} connected.\", client_id));\n    }\n\n    fn message(\u0026mut self, client_id: ClientId, message: MessagePayload, ctx: \u0026impl StateroomContext) {\n        let Some(message) = message.text() else {\n            return;\n        };\n\n        ctx.send_message(\n            MessageRecipient::Broadcast,\n            format!(\"User {:?} sent '{}'\", client_id, message),\n        );\n    }\n\n    fn disconnect(\u0026mut self, client_id: ClientId, ctx: \u0026impl StateroomContext) {\n        ctx.send_message(\n            MessageRecipient::Broadcast,\n            format!(\"User {:?} left.\", client_id),\n        );\n    }\n}\n```\n\nTo serve this service, we will compile it into a WebAssembly module. We import the `#[stateroom_wasm]`\nannotation macro and apply it to the existing `SharedCounter` declaration.\n\n```rust\nuse stateroom_wasm::*;\n\n#[stateroom_wasm]\n#[derive(Default)]\nstruct SharedCounter(i32);\n\nimpl StateroomService for SharedCounter {}\n```\n\nThen, install the `stateroom` command-line tool and the `wasm32-wasi` target, and run \n`stateroom dev`:\n\n```bash\n$ cargo install stateroom-cli\n$ rustup target add wasm32-wasi\n$ stateroom dev\n```\n\n`stateroom dev` will build your app and serve it on port `:8080`. Then, open\n`http://localhost:8080/status` in your browser -- if all went well, you should see the\nstatus message `ok`. Open up developer tools in your browser and type:\n\n```javascript\nlet ws = new WebSocket('ws://localhost:8080/ws');\nws.onmessage = (c) =\u003e console.log(c.data);\n```\n\nThis connects to your service, creating a new room with the id `1` if one doesn't exist\n(under default server settings, any string is a vaild room ID and connecting to a non-existant\nroom will create it).\n\nNow, you can increment the counter by sending the `increment` message using the `ws` handle:\n\n```javascript\nws.send('increment')\n```\n\nIf everything is set up correctly, the result will be printed out:\n\n```text\nnew value: 1\n```\n\nIf multiple clients are connected, each one will receive this message. Just like that, we have a mechanism for sharing some (very basic) application state between clients.\n\n## Modules\n\nStateroom has a modular architecture. If all you want to do is generate a Stateroom service to\nbe served with an existing Stateroom WebAssembly server, the main crates you will interact with\nwill probably be [`stateroom-cli`](/stateroom-cli), which provides a command-line tool, and\n[`stateroom-wasm`](/stateroom-wasm), the main Cargo dependency for building services.\n\n- [`stateroom`](https://docs.rs/stateroom/) is the core, minimal implementation of the service interface.\n- [`stateroom-cli`](https://docs.rs/stateroom-cli/) is a command-line interface for interacting with WebAssembly-compiled Stateroom services.\n- [`stateroom-server`](https://docs.rs/stateroom-server/) provides an [Axum](https://github.com/tokio-rs/axum)-based WebSocket server that runs a Stateroom service.\n- [`stateroom-wasm`](https://docs.rs/stateroom-wasm/) provides a macro for generating WebAssembly modules from Stateroom services.\n- [`stateroom-wasm-host`](https://docs.rs/stateroom-wasm-host/) provides a way to import Stateroom services from WebAssembly modules.\n\n## See Also\n\n[Aper](https://github.com/aper-dev/aper) is a state synchronization library which\nworks with Stateroom. \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjamsocket%2Fstateroom","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjamsocket%2Fstateroom","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjamsocket%2Fstateroom/lists"}