DioxusLabs / DioxusLabs/dioxus
Ship more lightweight alternative to dioxus-devtools for subsecond
- Dominant language
- Rust
- Stars
- 39.1k
- Forks
- 1.9k
- Avg merge
- 4d 10h
- Merged PRs (30d)
- 4
Description
## Feature Request
The current version of [dioxus-devtools](https://github.com/DioxusLabs/dioxus/blob/main/packages/devtools/Cargo.toml) depends on dioxus-core and dioxus-signals. However, none of those dependencies are required for [subsecond](https://github.com/DioxusLabs/dioxus/blob/main/packages/subsecond/subsecond/Cargo.toml) itself .
This means that downstream frameworks that add subsecond support, [like egor](https://github.com/wick3dr0se/egor#try-out-subsecond-hot-reloading) will typically add a much heavier dependency than necessary.
## Implement Suggestion
It would be lovely if either the dioxus specific bits were put behind a feature flag in dioxus-devtools, or if there were a separate subsecond-devtools crate.
For my own game, I'm currently using
```rs
use serde::Deserialize;
use std::path::PathBuf;
use subsecond::JumpTable;
/// Shamelessly stolen from https://github.com/DioxusLabs/dioxus/blob/main/packages/devtools/src/lib.rs#L88
/// But without the heavy dependencies
pub fn connect_subsecond() {
connect(move |msg| match msg {
DevserverMsg::HotReload(hot_reload_msg) => {
if let Some(jumptable) = hot_reload_msg.jump_table
&& hot_reload_msg.for_pid == Some(std::process::id())
{
unsafe { subsecond::apply_patch(jumptable).unwrap() };
}
}
_ => {}
});
}
pub fn connect(callback: impl FnMut(DevserverMsg) + Send + 'static) {
let Some(endpoint) = dioxus_cli_config::devserver_ws_endpoint() else {
return;
};
connect_at(endpoint, callback);
}
fn connect_at(endpoint: String, mut callback: impl FnMut(DevserverMsg) + Send + 'static) {
std::thread::spawn(move || {
let uri = format!(
"{endpoint}?aslr_reference={}&build_id={}&pid={}",
subsecond::aslr_reference(),
dioxus_cli_config::build_id(),
std::process::id()
);
let (mut websocket, _req) = match tungstenite::connect(uri) {
Ok((websocket, req)) => (websocket, req),
Err(_) => return,
};
while let Ok(msg) = websocket.read() {
if let tungstenite::Message::Text(text) = msg
&& let Ok(msg) = serde_json::from_str(&text)
{
callback(msg);
}
}
});
}
/// A message the hot reloading server sends to the client
#[non_exhaustive]
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub enum DevserverMsg {
/// Attempt a hotreload
/// This includes all the templates/literals/assets/binary patches that have changed in one shot
HotReload(HotReloadMsg),
/// Starting a hotpatch
HotPatchStart,
/// The devserver is starting a full rebuild.
FullReloadStart,
/// The full reload failed.
FullReloadFailed,
/// The app should reload completely if it can
FullReloadCommand,
/// The program is shutting down completely - maybe toss up a splash screen or something?
Shutdown,
}
#[derive(Debug, Default, Deserialize, Clone, PartialEq)]
pub struct HotReloadMsg {
// pub templates: Vec,
pub assets: Vec,
pub ms_elapsed: u64,
pub jump_table: Option,
pub for_build_id: Option,
pub for_pid: Option,
}
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.