spinta 0.1.1

Server-sent events client that works natively and on the web (WASM)
Documentation
use crate::{EsEvent, EventHandler, Result};
use gloo_events::EventListener;
use wasm_bindgen_futures::spawn_local;
use web_sys::Event;
use web_sys::EventSource;
use web_sys::EventSourceInit;
use web_sys::MessageEvent;

fn new_event_source(url: &str) -> Result<EventSource> {
    EventSource::new(url).map_err(|_| "couldn't aquire event source".to_string())
}

fn new_event_source_with_credentials(url: &str, credentials: bool) -> Result<EventSource> {
    EventSource::new_with_event_source_init_dict(
        url,
        EventSourceInit::new().with_credentials(credentials),
    )
    .map_err(|_| "couldn't aquire event source".to_string())
}

pub fn es_connect(url: String, on_event: EventHandler) -> Result<()> {
    spawn_local(async move {
        es_connect_async(url, on_event).await;
    });

    Ok(())
}

pub async fn es_connect_async(url: String, on_event: EventHandler) {
    use wasm_bindgen::JsCast as _;

    let es = new_event_source(&url).unwrap();

    let on_event: std::rc::Rc<dyn Send + Fn(EsEvent) -> std::ops::ControlFlow<()>> =
        on_event.into();

    let on_event = on_event.clone();

    {
        let on_event = on_event.clone();
        EventListener::new(&es, "error", move |event: &Event| {
            tracing::info!("error: {:?}", event);
            let on_event = on_event.clone();
            on_event(EsEvent::Error("Connect failed.".to_string()));
        });
    }

    {
        let on_event = on_event.clone();
        EventListener::new(&es, "open", move |_event: &Event| {
            on_event(EsEvent::Opened);
        });
    }

    {
        let on_event = on_event.clone();
        EventListener::new(&es, "message", move |event: &Event| {
            let event = event.dyn_ref::<MessageEvent>().unwrap();
            let text = event.data().as_string().expect("expect text data");
            // let id = event.last_event_id();
            on_event(EsEvent::Message(text));
        });
    }
}