nodevent

Crates.ionodevent
lib.rsnodevent
version0.1.2
created_at2025-11-14 14:42:53.401748+00
updated_at2025-11-14 15:06:41.718512+00
descriptionA simple Node.js-style event bus
homepagehttps://github.com/LengineerC/eventemitter-rs
repositoryhttps://github.com/LengineerC/eventemitter-rs
max_upload_size
id1933003
size26,876
(LengineerC)

documentation

README

nodevent

A Node.js-style event bus in Rust with synchronous and asynchronous support (via Tokio).

Installation

# Cargo.toml
[dependencies]
nodevent = { path = "../path_to_your_crate" }
tokio = { version = "1", features = ["full"] }

1. Single-Thread / Synchronous Event Handling

use nodevent::{SingleThreadEventEmitter, args};

fn main() {
    let emitter = SingleThreadEventEmitter::new();

    // Register a synchronous listener
    emitter.on("hello", |args| {
        let msg = args[0].downcast_ref::<String>().unwrap();
        println!("Hello received: {}", msg);
    });

    // Emit an event
    emitter.emit("hello", args!["world"]);

    // Register a once-only listener
    emitter.once("greet_once", |args| {
        let name = args[0].downcast_ref::<String>().unwrap();
        println!("Greetings, {}", name);
    });

    emitter.emit("greet_once", args!["Alice"]);
    emitter.emit("greet_once", args!["Bob"]); // Won't be called
}
  • on(event, callback): Registers a persistent listener.
  • once(event, callback): Registers a listener that is automatically removed after first call.
  • off(event, id): Removes a specific listener by its ID.
  • off_all(event): Removes all listeners for an event.
  • emit(event, args): Emits an event with Rc<Vec<Box<dyn Any>>> arguments.

2. Multi-Thread / Thread-Safe Event Handling

use nodevent::{MultiThreadEventEmitter, ts_args};
use std::sync::{Arc, Mutex};
use tokio::runtime::Runtime;

fn main() {
    let rt = Runtime::new().unwrap();
    let emitter = MultiThreadEventEmitter::new().set_handle(rt.handle().clone());
    let counter = Arc::new(Mutex::new(0));

    let counter_clone = counter.clone();
    emitter.on("increment", move |args| {
        let n = args[0].downcast_ref::<i32>().unwrap();
        *counter_clone.lock().unwrap() += n;
    });

    emitter.emit("increment", ts_args![5]);
    println!("Counter: {}", counter.lock().unwrap());
}
  • Use ts_args! to pass thread-safe arguments (Arc<Vec<Box<dyn Any + Send + Sync>>>).
  • Multi-threaded emitters require a tokio::runtime::Handle to run async tasks.

3. Asynchronous Event Handling

use nodevent::{MultiThreadEventEmitter, ts_args};
use tokio::runtime::Runtime;

async fn async_test(n: i32) {
    println!("Async event received: {}", n);
}

fn main() {
    let rt = Runtime::new().unwrap();
    let emitter = MultiThreadEventEmitter::new().set_handle(rt.handle().clone());

    // Register an async listener
    emitter.on_async("async_event", |args| {
        let n: i32 = *args[0].downcast_ref().unwrap();
        Box::pin(async move {
            async_test(n).await;
        })
    });

    // Register a once-only async listener
    emitter.once_async("async_once", |args| {
        let n: i32 = *args[0].downcast_ref().unwrap();
        Box::pin(async move {
            async_test(n).await;
            println!("Async once done: {}", n);
        })
    });

    emitter.emit("async_event", ts_args![42]);
    emitter.emit("async_once", ts_args![100]);

    // Wait for async tasks to finish
    rt.block_on(async {
        tokio::time::sleep(std::time::Duration::from_millis(10)).await;
    });
}
  • on_async / once_async require closures returning Pin<Box<dyn Future<Output = ()> + Send + Sync>>.
  • Use Box::pin(async move { ... }) inside the closure.

4. Macros

use nodevent::{args, ts_args};

// Synchronous args (single-threaded)
let sync_args = args![1, "hello", true];

// Thread-safe args (multi-threaded)
let safe_args = ts_args![42, "world", false];
  • args!: Wraps values into Box<dyn Any> inside Rc<Vec<_>>.
  • ts_args!: Wraps values into Box<dyn Any + Send + Sync> inside Arc<Vec<_>>.

5. Summary

Feature Macro / Method Thread Safety
Synchronous listener on / once Single-thread
Asynchronous listener on_async / once_async Multi-thread
Emit event emit Single/Multi-thread
Arguments args! / ts_args! Single / Multi-thread

This crate provides a flexible Node.js-style event bus in Rust, with full async support via Tokio and optional multi-threaded safety.

Commit count: 0

cargo fmt