liveview-native / liveview-native-core

Provides core language-agnostic functionality for LiveView Native across platforms
MIT License
146 stars 10 forks source link

Allow client to change LiveSocket URL #166

Open carson-katri opened 2 months ago

carson-katri commented 2 months ago

To support navigation, we need a way to change the URL the socket connects to when calling join_liveview_channel. This could be done in a few ways.

1. redirect passed to join_liveview_channel

The simplest method would be to add a redirect argument to join_liveview_channel.

pub async fn join_liveview_channel(&self, join_params: Option<HashMap<String, JSON>>, redirect: Option<String>) -> Result<LiveChannel, LiveSocketError>

This would be added to the join_payload under the "redirect" key.

https://github.com/liveview-native/liveview-native-core/blob/50b1d1e2fa4679e61e7bec682f0e0ebabe27f5cb/crates/core/src/live_socket/mod.rs#L690-L691

2 .url setter on LiveSocket

Alternatively, a setter for LiveSocket.url could be added. Then, calling join_liveview_channel would use whatever URL is set automatically.

There are a few issues with this approach:

  1. Core wouldn't know the original URL for reconnects. The client would have to keep track of the original URL separately for reconnects on live reload or error.
  2. It becomes ambiguous whether to pass url or redirect key in the join_payload. This could possibly be inferred by checking if a LiveChannel already exists.

3. Full browser-like navigation handling

This could be an additional feature of core built on top of another more manual solution.

The API could be based on the web's Navigation API.

The LiveSocket would be expanded with new methods like this:

fn navigate(&self, url: String, replace: bool)
fn reload(&self)
fn back(&self)
fn forward(&self)
fn traverseTo(&self, index: u32)

fn entries(&self) -> Vec<String>
fn set_event_handler(&self, handler: Box<dyn NavigationChangeHandler>)

When merge_diffs is called, core can check for the redirect/live_redirect events internally and call these methods. The client will react to navigation state changes through a bound NavigationChangeHandler.

simlay commented 2 months ago

I think Option 3 - Full browser-like navigation handling is the best path forward. It's a little bit more work and I'll have to fight an uphill battle with interior mutability but I think it's worth it.

In the mean time, I think option 1 is in #173 (if I get it to work).

mobile-bungalow commented 2 weeks ago

an additional constraint: it's been noted that maintaining a cache of dead renders per URLs is desired, a way to prehydrate the cache might be a long term goal.