From 32ec9cc57e6172f32e4fd76b54bfbe7a470af786 Mon Sep 17 00:00:00 2001 From: Greg Johnston Date: Sun, 8 Jan 2023 17:09:04 -0500 Subject: [PATCH] Prevent `create_signal_from_stream` from panicking on SSR --- examples/counter_isomorphic/src/counters.rs | 4 +-- leptos_reactive/src/signal.rs | 30 +++++++++++++++------ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/examples/counter_isomorphic/src/counters.rs b/examples/counter_isomorphic/src/counters.rs index d7e2d24..b09613a 100644 --- a/examples/counter_isomorphic/src/counters.rs +++ b/examples/counter_isomorphic/src/counters.rs @@ -209,8 +209,8 @@ pub fn MultiuserCounter(cx: Scope) -> impl IntoView { }; #[cfg(feature = "ssr")] - let multiplayer_value = - create_signal_from_stream(cx, futures::stream::once(Box::pin(async { 0.to_string() }))); + let (multiplayer_value, _) = + create_signal(cx, None::); view! { cx, diff --git a/leptos_reactive/src/signal.rs b/leptos_reactive/src/signal.rs index 2616add..b08077e 100644 --- a/leptos_reactive/src/signal.rs +++ b/leptos_reactive/src/signal.rs @@ -1,8 +1,9 @@ use crate::{ debug_warn, runtime::{with_runtime, RuntimeId}, - spawn_local, Runtime, Scope, ScopeProperty, UntrackedGettableSignal, UntrackedSettableSignal, + Runtime, Scope, ScopeProperty, UntrackedGettableSignal, UntrackedSettableSignal, }; +use cfg_if::cfg_if; use futures::Stream; use std::{fmt::Debug, marker::PhantomData}; use thiserror::Error; @@ -67,6 +68,9 @@ pub fn create_signal(cx: Scope, value: T) -> (ReadSignal, WriteSignal) /// [Stream](futures::stream::Stream). /// If the stream has not yet emitted a value since the signal was created, the signal's /// value will be `None`. +/// +/// **Note**: If used on the server side during server rendering, this will return `None` +/// immediately and not begin driving the stream. #[cfg_attr( debug_assertions, instrument( @@ -79,17 +83,27 @@ pub fn create_signal(cx: Scope, value: T) -> (ReadSignal, WriteSignal) )] pub fn create_signal_from_stream( cx: Scope, + #[allow(unused_mut)] // allowed because needed for SSR mut stream: impl Stream + Unpin + 'static, ) -> ReadSignal> { - use futures::StreamExt; + cfg_if! { + if #[cfg(feature = "ssr")] { + _ = stream; + let (read, _) = create_signal(cx, None); + read + } else { + use crate::spawn_local; + use futures::StreamExt; - let (read, write) = create_signal(cx, None); - spawn_local(async move { - while let Some(value) = stream.next().await { - write.set(Some(value)); + let (read, write) = create_signal(cx, None); + spawn_local(async move { + while let Some(value) = stream.next().await { + write.set(Some(value)); + } + }); + read } - }); - read + } } /// The getter for a reactive signal.