Summary
I'd like to propose adding a higher-level API that abstracts away SSE implementation details, similar to the official Go SDK's datastar.NewSSE() pattern.
Motivation
The current API requires users to:
- Create event objects manually (
PatchElements::new(), PatchSignals::new())
- Call framework-specific conversion methods (
.write_as_axum_sse_event())
- Wrap in
Ok() and yield to the stream
This is verbose and exposes SSE implementation details that most users don't need to think about.
Proposed API
use datastar::axum::sse;
async fn handler(ReadSignals(signals): ReadSignals<Signals>) -> impl IntoResponse {
Sse::new(stream_fn(move |yielder| async move {
let mut sse = sse(yielder);
// Simple, ergonomic methods
sse.patch_elements("<div id='msg'>Hello</div>").await;
sse.remove_element("#temp").await;
sse.patch_signals(r#"{"count": 1}"#).await;
sse.execute_script("console.log('hi')").await;
sse.redirect("/dashboard").await;
// For advanced options, use _with variants
sse.patch_elements_with(
PatchElements::new(html)
.selector("#feed")
.mode(ElementPatchMode::After)
).await;
}))
}
Comparison with Go SDK
The Go SDK provides this pattern:
sse := datastar.NewSSE(w, r)
sse.PatchElements(html)
sse.RemoveElement("#temp")
sse.MarshalAndPatchSignals(map[string]any{"count": 1})
sse.ExecuteScript(`console.log("hello")`)
sse.Redirect("/new-page")
Implementation Approach
- Add
ServerSentEventGenerator<Y> struct with an SseYielder trait
- Add framework-specific yielder wrappers (
AxumYielder, WarpYielder)
- Add
sse() factory functions in each framework module
- Add
asynk-strim as an optional dependency behind a feature flag
- Fully backward compatible - existing API remains unchanged
Questions
- Does this align with the direction you'd like for the SDK?
- Any concerns about adding
asynk-strim as a dependency?
- Naming preferences? (
ServerSentEventGenerator matches Go, or something shorter?)
I have a working implementation ready if you're interested.
Summary
I'd like to propose adding a higher-level API that abstracts away SSE implementation details, similar to the official Go SDK's
datastar.NewSSE()pattern.Motivation
The current API requires users to:
PatchElements::new(),PatchSignals::new()).write_as_axum_sse_event())Ok()and yield to the streamThis is verbose and exposes SSE implementation details that most users don't need to think about.
Proposed API
Comparison with Go SDK
The Go SDK provides this pattern:
Implementation Approach
ServerSentEventGenerator<Y>struct with anSseYieldertraitAxumYielder,WarpYielder)sse()factory functions in each framework moduleasynk-strimas an optional dependency behind a feature flagQuestions
asynk-strimas a dependency?ServerSentEventGeneratormatches Go, or something shorter?)I have a working implementation ready if you're interested.