elo_index_client/
elo_index_client.rs

1use loro::LoroDoc;
2use loro_websocket_client::LoroWebsocketClient;
3use std::sync::Arc;
4use tokio::time::{sleep, Duration};
5
6const KEY: [u8; 32] = [
7    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
8    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
9];
10
11#[tokio::main(flavor = "current_thread")]
12async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
13    // Args: role receiver|sender, url, room
14    let mut args = std::env::args().skip(1).collect::<Vec<_>>();
15    if args.len() < 3 {
16        eprintln!("usage: elo_index_client <receiver|sender> <ws_url> <room_id>");
17        std::process::exit(2);
18    }
19    let role = args.remove(0);
20    let url = args.remove(0);
21    let room = args.remove(0);
22
23    let client = LoroWebsocketClient::connect(&url).await?;
24    let doc = Arc::new(tokio::sync::Mutex::new(LoroDoc::new()));
25
26    match role.as_str() {
27        "sender" => {
28            // Prepare desired state before join so adaptor sends it as initial snapshot
29            {
30                let d = doc.lock().await;
31                d.get_text("t").insert(0, "hi").unwrap();
32                d.commit();
33            }
34            let _room = client
35                .join_elo_with_adaptor(&room, doc.clone(), "k1".to_string(), KEY)
36                .await?;
37            // Allow time for the async writer and server broadcast to complete.
38            // Align with JS wrapper's 800ms flush to avoid flakiness in cross-lang tests.
39            sleep(Duration::from_millis(800)).await;
40            Ok(())
41        }
42        "receiver" => {
43            let _room = client
44                .join_elo_with_adaptor(&room, doc.clone(), "k1".to_string(), KEY)
45                .await?;
46            // Poll document until expected content arrives
47            let deadline = tokio::time::Instant::now() + Duration::from_secs(10);
48            loop {
49                {
50                    let d = doc.lock().await;
51                    let s = d.get_text("t").to_string();
52                    if s == "hi" {
53                        println!("INDEXED 1");
54                        return Ok(());
55                    }
56                }
57                if tokio::time::Instant::now() > deadline {
58                    eprintln!("timeout waiting for content");
59                    std::process::exit(1);
60                }
61                sleep(Duration::from_millis(50)).await;
62            }
63        }
64        _ => {
65            eprintln!("usage: elo_index_client <receiver|sender> <ws_url> <room_id>");
66            std::process::exit(2);
67        }
68    }
69}