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.json from 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.json from 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.
Description
No description provided
Readme 525 KiB
Languages
Rust 90.6%
CSS 9.4%