# Research Synthesis — In-Browser Swactor Runtime ## Ecosystem Landscape No established Rust actor framework runs natively in browsers. The closest projects: - **Lunatic** — Erlang-inspired Wasm actor runtime using wasmtime (server-side, not browser). Uses preemptive scheduling and work-stealing. Not applicable to browser constraints. - **wasmCloud** — CNCF distributed actor platform. Single-threaded actors, NATS-backed lattice. Cloud/edge focus, no browser target. - **Actix** — Tokio-dependent, network stack doesn't compile for wasm32. Community attempts to port failed due to `net2`/tokio dependencies. **Implication**: swactor would be the first Rust actor runtime with true multi-threaded browser execution via wasm-threads. This is a differentiated position. ## Existing Work in This Codebase | Component | Status | Notes | |-----------|--------|-------| | `crates/wasm/` | Basic PoC | Hardcoded Counter/Relay actors, manual tick, u32-only messages | | `no_random` feature | Working | Deterministic address generation without `getrandom` | | `tick()` method | Working | Single-threaded tick for manual driving | | Actor watching | In core | `ExitReason`, `ActorExited`, `on_actor_exit`, `WatchRegistry` | | swactor-std | Complete | StdExtension, naming, groups, monitoring, supervisor | ## Platform Dependencies Analysis ### Works as-is with wasm-threads - `crossbeam-queue` (ArrayQueue, SegQueue) — uses `core::sync::atomic` - `std::sync::{Mutex, RwLock}` — stdlib uses futex on wasm with atomics - `std::sync::atomic::*` — maps to wasm atomic instructions - `Arc` — works with atomics - `std::sync::OnceLock` — works with atomics ### Requires platform abstraction (4 items) 1. `std::thread::spawn` → Web Worker via `web-sys::Worker` 2. `thread::park_timeout` / `Thread::unpark` → `Atomics.wait` / `Atomics.notify` 3. `thread::yield_now` → no-op (or `Atomics.wait(0)` as hint) 4. `std::time::Instant` → `web_time::Instant` (drop-in crate) ## Priority Ranking ### P0 — Must Have (enables everything else) 1. **Platform abstraction layer** — cfg-gated replacements for thread spawn, park/unpark, yield, Instant. Core swactor compiles for wasm32 with atomics. 2. **Single-worker browser runtime** — Prove the runtime works in a browser. One Web Worker, auto-scheduled tick loop, generic JS API for spawn/send/recv. 3. **Multi-worker parallelism** — N Web Workers sharing runtime state via SharedArrayBuffer. Full utilization of browser CPU cores. ### P1 — Should Have (full actor system) 4. **Actor watching in browser** — Death notifications, exit reasons. Already in core, just needs to compile and pass wasm tests. 5. **swactor-std in browser** — Naming, groups, monitoring extensions. Compile and test for wasm32. 6. **Stats and introspection** — Runtime stats accessible from JS. Worker info, actor counts, message throughput. ### P2 — Important (distributed peer) 7. **WebSocket transport** — Adapter implementing swactor's transport traits over WebSocket. Browser node joins a distributed cluster. 8. **Browser-to-browser transport foundation** — WebRTC DataChannel scaffolding for future STUN/TURN. ### P3 — Nice to Have (developer experience) 9. **TypeScript type generation** — Derive TS interfaces from Rust actor message types. 10. **Build tooling** — wasm-pack wrapper script, example project template, CI configuration. 11. **Browser dev tools** — Actor inspector, message flow visualization, performance profiling. ### P4 — Future (out of scope for this feature phase) 12. **STUN/TURN integration** — Full NAT traversal for peer-to-peer browser connections. 13. **Hot code reload** — Swap actor implementations without restarting the runtime. 14. **Wasm component model** — Migrate from wasm-bindgen to component model when stabilized. ## Key Design Decisions | Decision | Choice | Rationale | |----------|--------|-----------| | Threading model | SharedArrayBuffer + wasm-threads | swactor's shared-memory architecture (Arc, crossbeam queues, atomics) maps directly. postMessage isolation would require a rewrite. | | Scheduling | `setTimeout(0)` tight loop | `requestAnimationFrame` caps at 60Hz. setTimeout(0) gives ~4ms resolution, sufficient for actor ticks. For rendering-coupled actors, RAF can be opt-in. | | Actor definition | Rust only | Keeps the type system intact. JS actors would require dynamic dispatch and lose compile-time guarantees. | | Platform abstraction approach | cfg-gated type aliases + inline functions | Minimal invasion. No trait-based HAL, no new modules. Just swap `std::time::Instant` → `web_time::Instant` etc. | | Browser crate location | New `crates/wasm-browser/` | Clean separation from the existing PoC. The old `crates/wasm/` can be deprecated or kept as a minimal example. | ## Risk Assessment | Risk | Likelihood | Impact | Mitigation | |------|-----------|--------|------------| | crossbeam-queue doesn't compile for wasm32+atomics | Low | High | Test early in Stage 1. Fallback: thin wrapper over `VecDeque` behind cfg. | | COOP/COEP headers break third-party integrations | Medium | Medium | Document clearly. This is the standard trade-off for SharedArrayBuffer apps. | | Nightly Rust + build-std is unstable | Medium | Medium | Pin to a known-good nightly. Revisit when wasm-threads stabilizes. | | Web Worker spawn latency | Low | Low | Spawn workers eagerly at runtime init, not per-actor. | | Browser compatibility gaps | Low | Medium | Target Chrome/Firefox/Safari latest. All support SharedArrayBuffer since 2021. |