3.6 KiB
Development
Your new bare-bones project includes minimal organization with a single main.rs file and a few assets.
project/
├─ assets/ # Any assets that are used by the app should be placed here
├─ src/
│ ├─ main.rs # main.rs is the entry point to your application and currently contains all components for the app
├─ Cargo.toml # The Cargo.toml file defines the dependencies and feature flags for your project
Serving Your App
Run the following command in the root of your project to start developing with the default platform:
dx serve
To run for a different platform, use the --platform platform flag. E.g.
dx serve --platform desktop
Configuration (appsettings.json and WASM fast-path)
This project supports an appsettings.json-style configuration that is loaded at runtime.
- Native (desktop/server): the app tries to read
appsettings.jsonfrom the working directory. - WASM (web): the loader will first try a small HTML-injection fast-path (see below). If that
is not present it will fetch
appsettings.jsonfrom the hosting origin.
Example appsettings.json:
{
"server": {
"stun_server": "stun:stun.l.google.com:19302"
}
}
HTML injection fast-path (for embedding a small config directly in index.html):
<script id="app-config" type="application/json">{
"server": { "stun_server": "stun:stun.l.google.com:19302" }
}</script>
This is useful for static hosting scenarios where you want to provide a different runtime configuration without rebuilding the WASM artifact.
Consuming the Config in the UI (Dioxus)
The Dioxus app provides a Signal<Config> via the hooks context. Child components can consume
it with:
let cfg_signal = use_context::<Signal<niom_webrtc::config::Config>>();
let cfg = cfg_signal.get(); // or cfg_signal.read()/() depending on the signal API
// use cfg.server.stun_server
The app uses an async loader (via use_resource) and overwrites the initial default config when
the runtime-loaded config becomes available. This gives instant sensible defaults while still
allowing runtime overrides.
Example: Provider + Consumer (Dioxus)
Below is a minimal example showing how the app creates a Signal<Config> provider and how a
child component consumes it. This pattern gives children an immediately-available default
config while an async fetch can replace it at runtime.
use dioxus::prelude::*;
use dioxus_hooks::use_resource;
use niom_webrtc::config;
#[allow(non_snake_case)]
fn ConfigProvider(cx: Scope) -> Element {
// synchronous immediate default
let default_cfg = config::load_config_sync_or_default();
// a reactive signal holding the current config
let cfg_signal = use_state(cx, || default_cfg.clone());
// async resource that loads runtime config (WASM fetch or native file)
let resource = use_resource(cx, (), |_| async move { config::load_config_or_default().await });
// when resource completes, update the signal so children react
if let Some(cfg) = resource.value() {
cfg_signal.set(cfg.clone());
}
// provide the signal to descendants
use_context_provider(cx, || cfg_signal.clone());
cx.render(rsx! { children(&cx) })
}
fn SomeChild(cx: Scope) -> Element {
let cfg_signal = use_context::<UseStateHandle<config::Config>>(cx);
let cfg = cfg_signal.get();
cx.render(rsx!(div { "STUN: {cfg.server.stun_server}" }))
}
Notes:
load_config_sync_or_default()returns a sensible default immediately (plus HTML fast-path on WASM).load_config_or_default()is async and will perform a network fetch on WASM if the HTML fast-path wasn't present.