mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-04-07 10:22:29 +02:00
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
This commit is contained in:
5
.changes/cli-static-files-hot-reload.md
Normal file
5
.changes/cli-static-files-hot-reload.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"cli.rs": "minor"
|
||||
---
|
||||
|
||||
Hot-reload the frontend when `tauri.conf.json > build > devPath` points to a directory.
|
||||
5
.changes/utils-mimetype.md
Normal file
5
.changes/utils-mimetype.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"tauri-utils": "patch"
|
||||
---
|
||||
|
||||
Add `mime_type` module.
|
||||
@@ -30,7 +30,6 @@ tauri-utils = { version = "1.1.1", path = "../tauri-utils" }
|
||||
uuid = { version = "1", features = [ "v4" ] }
|
||||
http = "0.2.4"
|
||||
http-range = "0.1.4"
|
||||
infer = "0.7"
|
||||
raw-window-handle = "0.5"
|
||||
rand = "0.8"
|
||||
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// custom wry types
|
||||
mod mime_type;
|
||||
mod request;
|
||||
mod response;
|
||||
|
||||
pub use self::{
|
||||
mime_type::MimeType,
|
||||
request::{Request, RequestParts},
|
||||
response::{Builder as ResponseBuilder, Response, ResponseParts},
|
||||
};
|
||||
|
||||
pub use tauri_utils::mime_type::MimeType;
|
||||
|
||||
// re-expose default http types
|
||||
pub use http::{header, method, status, uri::InvalidUri, version, Uri};
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ glob = { version = "0.3.0", optional = true }
|
||||
walkdir = { version = "2", optional = true }
|
||||
memchr = "2.4"
|
||||
semver = "1"
|
||||
infer = "0.7"
|
||||
|
||||
[target."cfg(target_os = \"linux\")".dependencies]
|
||||
heck = "0.4"
|
||||
|
||||
@@ -14,6 +14,7 @@ pub mod assets;
|
||||
pub mod config;
|
||||
pub mod html;
|
||||
pub mod io;
|
||||
pub mod mime_type;
|
||||
pub mod platform;
|
||||
/// Prepare application resources and sidecars.
|
||||
#[cfg(feature = "resources")]
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! Determine a mime type from a URI or file contents.
|
||||
|
||||
use std::fmt;
|
||||
|
||||
const MIMETYPE_PLAIN: &str = "text/plain";
|
||||
|
||||
/// [Web Compatible MimeTypes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#important_mime_types_for_web_developers)
|
||||
#[allow(missing_docs)]
|
||||
pub enum MimeType {
|
||||
Css,
|
||||
Csv,
|
||||
245
tooling/cli/Cargo.lock
generated
245
tooling/cli/Cargo.lock
generated
@@ -91,6 +91,17 @@ version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d67af77d68a931ecd5cbd8a3b5987d63a1d1d1278f7f6a60ae33db485cdebb69"
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "attohttpc"
|
||||
version = "0.22.0"
|
||||
@@ -121,6 +132,56 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "axum"
|
||||
version = "0.5.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c9e3356844c4d6a6d6467b8da2cffb4a2820be256f50a3a386c9d152bab31043"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum-core",
|
||||
"base64",
|
||||
"bitflags",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"itoa 1.0.2",
|
||||
"matchit",
|
||||
"memchr",
|
||||
"mime",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"sha-1 0.10.0",
|
||||
"sync_wrapper",
|
||||
"tokio",
|
||||
"tokio-tungstenite",
|
||||
"tower",
|
||||
"tower-http",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum-core"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9f0c0a60006f2a293d82d571f635042a72edf927539b7685bd62d361963839b"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http-body",
|
||||
"mime",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.0"
|
||||
@@ -277,6 +338,27 @@ dependencies = [
|
||||
"jobserver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfb"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74f89d248799e3f15f91b70917f65381062a01bb8e222700ea0e5a7ff9785f9c"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"uuid 0.8.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfb"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"fnv",
|
||||
"uuid 1.1.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
@@ -729,16 +811,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "exr"
|
||||
version = "1.4.2"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14cc0e06fb5f67e5d6beadf3a382fec9baca1aa751c6d5368fdeee7e5932c215"
|
||||
checksum = "c9a7880199e74c6d3fe45579df2f436c5913a71405494cb89d59234d86b47dc5"
|
||||
dependencies = [
|
||||
"bit_field",
|
||||
"deflate",
|
||||
"flume",
|
||||
"half",
|
||||
"inflate",
|
||||
"lebe",
|
||||
"miniz_oxide",
|
||||
"smallvec",
|
||||
"threadpool",
|
||||
]
|
||||
@@ -912,9 +993,9 @@ checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68"
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.21"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868"
|
||||
checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
@@ -930,6 +1011,7 @@ checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
@@ -1148,6 +1230,12 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http-range-header"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29"
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.8.0"
|
||||
@@ -1227,9 +1315,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.24.3"
|
||||
version = "0.24.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e30ca2ecf7666107ff827a8e481de6a132a9b687ed3bb20bb1c144a36c00964"
|
||||
checksum = "bd8e4fb07cf672b1642304e731ef8a6a4c7891d67bb4fd4f5ce58cd6ed86803c"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"byteorder",
|
||||
@@ -1275,12 +1363,21 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inflate"
|
||||
version = "0.4.5"
|
||||
name = "infer"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff"
|
||||
checksum = "20b2b533137b9cad970793453d4f921c2e91312a6d88b1085c07bc15fc51bb3b"
|
||||
dependencies = [
|
||||
"adler32",
|
||||
"cfb 0.6.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "infer"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f178e61cdbfe084aa75a2f4f7a25a5bb09701a47ae1753608f194b15783c937a"
|
||||
dependencies = [
|
||||
"cfb 0.7.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1471,9 +1568,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "lebe"
|
||||
version = "0.5.1"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7efd1d698db0759e6ef11a7cd44407407399a910c774dd804c64c032da7826ff"
|
||||
checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
@@ -1572,6 +1669,12 @@ version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
|
||||
|
||||
[[package]]
|
||||
name = "matchit"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb"
|
||||
|
||||
[[package]]
|
||||
name = "md5"
|
||||
version = "0.7.0"
|
||||
@@ -1618,9 +1721,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.5.3"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc"
|
||||
checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
@@ -2119,7 +2222,7 @@ checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
|
||||
dependencies = [
|
||||
"maplit",
|
||||
"pest",
|
||||
"sha-1",
|
||||
"sha-1 0.8.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2862,6 +2965,17 @@ dependencies = [
|
||||
"opaque-debug 0.2.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha-1"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"cpufeatures",
|
||||
"digest 0.10.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.10.1"
|
||||
@@ -3034,6 +3148,12 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sync_wrapper"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8"
|
||||
|
||||
[[package]]
|
||||
name = "sysctl"
|
||||
version = "0.4.4"
|
||||
@@ -3100,6 +3220,7 @@ name = "tauri-cli"
|
||||
version = "1.1.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum",
|
||||
"base64",
|
||||
"clap 3.2.7",
|
||||
"colored",
|
||||
@@ -3109,11 +3230,14 @@ dependencies = [
|
||||
"glob",
|
||||
"handlebars",
|
||||
"heck 0.4.0",
|
||||
"html5ever",
|
||||
"ignore",
|
||||
"image",
|
||||
"include_dir",
|
||||
"infer 0.9.0",
|
||||
"json-patch",
|
||||
"jsonschema",
|
||||
"kuchiki",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"log",
|
||||
@@ -3132,6 +3256,7 @@ dependencies = [
|
||||
"tauri-icns",
|
||||
"tauri-utils",
|
||||
"tempfile",
|
||||
"tokio",
|
||||
"toml",
|
||||
"toml_edit",
|
||||
"unicode-width",
|
||||
@@ -3172,6 +3297,7 @@ dependencies = [
|
||||
"glob",
|
||||
"heck 0.4.0",
|
||||
"html5ever",
|
||||
"infer 0.7.0",
|
||||
"json-patch",
|
||||
"json5",
|
||||
"kuchiki",
|
||||
@@ -3352,9 +3478,33 @@ dependencies = [
|
||||
"once_cell",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-tungstenite"
|
||||
version = "0.17.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"log",
|
||||
"tokio",
|
||||
"tungstenite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.4"
|
||||
@@ -3389,6 +3539,47 @@ dependencies = [
|
||||
"itertools",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"pin-project",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-http"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c530c8675c1dbf98facee631536fa116b5fb6382d7dd6dc1b118d970eafe3ba"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http-body",
|
||||
"http-range-header",
|
||||
"pin-project-lite",
|
||||
"tower",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-layer"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62"
|
||||
|
||||
[[package]]
|
||||
name = "tower-service"
|
||||
version = "0.3.2"
|
||||
@@ -3402,6 +3593,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"log",
|
||||
"pin-project-lite",
|
||||
"tracing-core",
|
||||
]
|
||||
@@ -3430,6 +3622,25 @@ version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
|
||||
|
||||
[[package]]
|
||||
name = "tungstenite"
|
||||
version = "0.17.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"http",
|
||||
"httparse",
|
||||
"log",
|
||||
"rand 0.8.5",
|
||||
"sha-1 0.10.0",
|
||||
"thiserror",
|
||||
"url",
|
||||
"utf-8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.15.0"
|
||||
|
||||
@@ -76,6 +76,12 @@ log = { version = "0.4.17", features = [ "kv_unstable", "kv_unstable_std" ] }
|
||||
env_logger = "0.9.0"
|
||||
icns = { package = "tauri-icns", version = "0.1" }
|
||||
image = { version = "0.24", default-features = false, features = [ "ico" ] }
|
||||
axum = { version = "0.5.16", features = ["ws"] }
|
||||
html5ever = "0.25"
|
||||
infer = "0.9"
|
||||
kuchiki = "0.8"
|
||||
tokio = { version = "1.21.1", features = ["macros", "sync"] }
|
||||
|
||||
|
||||
[target."cfg(windows)".dependencies]
|
||||
winapi = { version = "0.3", features = [ "handleapi", "processenv", "winbase", "wincon", "winnt" ] }
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::{
|
||||
helpers::{
|
||||
app_paths::{app_dir, tauri_dir},
|
||||
command_env,
|
||||
config::{get as get_config, AppUrl, BeforeDevCommand, WindowUrl},
|
||||
config::{get as get_config, reload as reload_config, AppUrl, BeforeDevCommand, WindowUrl},
|
||||
},
|
||||
interface::{AppInterface, ExitReason, Interface},
|
||||
CommandExt, Result,
|
||||
@@ -202,16 +202,42 @@ fn command_internal(mut options: Options) -> Result<()> {
|
||||
cargo_features.extend(features.clone());
|
||||
}
|
||||
|
||||
let mut dev_path = config
|
||||
.lock()
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.build
|
||||
.dev_path
|
||||
.clone();
|
||||
if let AppUrl::Url(WindowUrl::App(path)) = &dev_path {
|
||||
use crate::helpers::web_dev_server::{start_dev_server, SERVER_URL};
|
||||
if path.exists() {
|
||||
let path = path.canonicalize()?;
|
||||
start_dev_server(path);
|
||||
dev_path = AppUrl::Url(WindowUrl::External(SERVER_URL.parse().unwrap()));
|
||||
|
||||
// TODO: in v2, use an env var to pass the url to the app context
|
||||
// or better separate the config passed from the cli internally and
|
||||
// config passed by the user in `--config` into to separate env vars
|
||||
// and the context merges, the user first, then the internal cli config
|
||||
if let Some(c) = options.config {
|
||||
let mut c: tauri_utils::config::Config = serde_json::from_str(&c)?;
|
||||
c.build.dev_path = dev_path.clone();
|
||||
options.config = Some(serde_json::to_string(&c).unwrap());
|
||||
} else {
|
||||
options.config = Some(format!(
|
||||
r#"{{ "build": {{ "devPath": "{}" }} }}"#,
|
||||
SERVER_URL
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let config = reload_config(options.config.as_deref())?;
|
||||
|
||||
if std::env::var_os("TAURI_SKIP_DEVSERVER_CHECK") != Some("true".into()) {
|
||||
if let AppUrl::Url(WindowUrl::External(dev_server_url)) = config
|
||||
.lock()
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.build
|
||||
.dev_path
|
||||
.clone()
|
||||
{
|
||||
if let AppUrl::Url(WindowUrl::External(dev_server_url)) = dev_path {
|
||||
let host = dev_server_url
|
||||
.host()
|
||||
.unwrap_or_else(|| panic!("No host name in the URL"));
|
||||
|
||||
29
tooling/cli/src/helpers/auto-reload.js
Normal file
29
tooling/cli/src/helpers/auto-reload.js
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
// taken from https://github.com/thedodd/trunk/blob/5c799dc35f1f1d8f8d3d30c8723cbb761a9b6a08/src/autoreload.js
|
||||
|
||||
(function () {
|
||||
var url = 'ws:' + '//' + window.location.host + '/_tauri-cli/ws';
|
||||
var poll_interval = 5000;
|
||||
var reload_upon_connect = () => {
|
||||
window.setTimeout(
|
||||
() => {
|
||||
// when we successfully reconnect, we'll force a
|
||||
// reload (since we presumably lost connection to
|
||||
// trunk due to it being killed, so it will have
|
||||
// rebuilt on restart)
|
||||
var ws = new WebSocket(url);
|
||||
ws.onopen = () => window.location.reload();
|
||||
ws.onclose = reload_upon_connect;
|
||||
},
|
||||
poll_interval);
|
||||
};
|
||||
|
||||
var ws = new WebSocket(url);
|
||||
ws.onmessage = (ev) => {
|
||||
const msg = JSON.parse(ev.data);
|
||||
if (msg.reload) {
|
||||
window.location.reload();
|
||||
}
|
||||
};
|
||||
ws.onclose = reload_upon_connect;
|
||||
})()
|
||||
@@ -7,6 +7,7 @@ pub mod config;
|
||||
pub mod framework;
|
||||
pub mod template;
|
||||
pub mod updater_signature;
|
||||
pub mod web_dev_server;
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
|
||||
154
tooling/cli/src/helpers/web_dev_server.rs
Normal file
154
tooling/cli/src/helpers/web_dev_server.rs
Normal file
@@ -0,0 +1,154 @@
|
||||
use axum::{
|
||||
extract::{ws::WebSocket, WebSocketUpgrade},
|
||||
http::{header::CONTENT_TYPE, Request, StatusCode},
|
||||
response::IntoResponse,
|
||||
routing::get,
|
||||
Router, Server,
|
||||
};
|
||||
use html5ever::{namespace_url, ns, LocalName, QualName};
|
||||
use kuchiki::{traits::TendrilSink, NodeRef};
|
||||
use notify::{watcher, DebouncedEvent, RecursiveMode, Watcher};
|
||||
use std::{
|
||||
net::SocketAddr,
|
||||
path::{Path, PathBuf},
|
||||
str::FromStr,
|
||||
sync::Arc,
|
||||
thread,
|
||||
time::Duration,
|
||||
};
|
||||
use tauri_utils::mime_type::MimeType;
|
||||
use tokio::sync::broadcast::{channel, Sender};
|
||||
|
||||
const AUTO_RELOAD_SCRIPT: &str = include_str!("./auto-reload.js");
|
||||
pub const SERVER_URL: &str = "http://127.0.0.1:1430";
|
||||
|
||||
struct State {
|
||||
serve_dir: PathBuf,
|
||||
tx: Sender<()>,
|
||||
}
|
||||
|
||||
pub fn start_dev_server<P: AsRef<Path>>(path: P) {
|
||||
let serve_dir = path.as_ref().to_path_buf();
|
||||
|
||||
std::thread::spawn(move || {
|
||||
tokio::runtime::Builder::new_current_thread()
|
||||
.enable_io()
|
||||
.build()
|
||||
.unwrap()
|
||||
.block_on(async move {
|
||||
let (tx, _) = channel(1);
|
||||
|
||||
let tokio_tx = tx.clone();
|
||||
let serve_dir_ = serve_dir.clone();
|
||||
thread::spawn(move || {
|
||||
let (tx, rx) = std::sync::mpsc::channel();
|
||||
let mut watcher = watcher(tx, Duration::from_secs(1)).unwrap();
|
||||
watcher.watch(serve_dir_, RecursiveMode::Recursive).unwrap();
|
||||
|
||||
loop {
|
||||
if let Ok(e) = rx.recv() {
|
||||
match e {
|
||||
DebouncedEvent::Create(_)
|
||||
| DebouncedEvent::Remove(_)
|
||||
| DebouncedEvent::Rename(_, _)
|
||||
| DebouncedEvent::Write(_) => {
|
||||
let _ = tokio_tx.send(());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let state = Arc::new(State { serve_dir, tx });
|
||||
let router = Router::new()
|
||||
.fallback(
|
||||
Router::new().nest(
|
||||
"/",
|
||||
get({
|
||||
let state = state.clone();
|
||||
move |req| handler(req, state)
|
||||
})
|
||||
.handle_error(|_error| async move { StatusCode::INTERNAL_SERVER_ERROR }),
|
||||
),
|
||||
)
|
||||
.route(
|
||||
"/_tauri-cli/ws",
|
||||
get(move |ws: WebSocketUpgrade| async move {
|
||||
ws.on_upgrade(|socket| async move { ws_handler(socket, state).await })
|
||||
}),
|
||||
);
|
||||
Server::bind(&SocketAddr::from_str(SERVER_URL.split('/').nth(2).unwrap()).unwrap())
|
||||
.serve(router.into_make_service())
|
||||
.await
|
||||
.unwrap();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
async fn handler<T>(req: Request<T>, state: Arc<State>) -> impl IntoResponse {
|
||||
let uri = req.uri().to_string();
|
||||
let uri = if uri == "/" {
|
||||
&uri
|
||||
} else {
|
||||
uri.strip_prefix('/').unwrap_or(&uri)
|
||||
};
|
||||
|
||||
let file = std::fs::read(state.serve_dir.join(&uri))
|
||||
.or_else(|_| std::fs::read(state.serve_dir.join(format!("{}.html", &uri))))
|
||||
.or_else(|_| std::fs::read(state.serve_dir.join(format!("{}/index.html", &uri))))
|
||||
.or_else(|_| std::fs::read(state.serve_dir.join("index.html")));
|
||||
|
||||
file
|
||||
.map(|mut f| {
|
||||
let mime_type = MimeType::parse(&f, uri);
|
||||
if mime_type == MimeType::Html.to_string() {
|
||||
let mut document = kuchiki::parse_html().one(String::from_utf8_lossy(&f).into_owned());
|
||||
fn with_html_head<F: FnOnce(&NodeRef)>(document: &mut NodeRef, f: F) {
|
||||
if let Ok(ref node) = document.select_first("head") {
|
||||
f(node.as_node())
|
||||
} else {
|
||||
let node = NodeRef::new_element(
|
||||
QualName::new(None, ns!(html), LocalName::from("head")),
|
||||
None,
|
||||
);
|
||||
f(&node);
|
||||
document.prepend(node)
|
||||
}
|
||||
}
|
||||
|
||||
with_html_head(&mut document, |head| {
|
||||
let script_el =
|
||||
NodeRef::new_element(QualName::new(None, ns!(html), "script".into()), None);
|
||||
script_el.append(NodeRef::new_text(AUTO_RELOAD_SCRIPT));
|
||||
head.prepend(script_el);
|
||||
});
|
||||
|
||||
f = document.to_string().as_bytes().to_vec();
|
||||
}
|
||||
|
||||
(StatusCode::OK, [(CONTENT_TYPE, mime_type)], f)
|
||||
})
|
||||
.unwrap_or_else(|_| {
|
||||
(
|
||||
StatusCode::NOT_FOUND,
|
||||
[(CONTENT_TYPE, "text/plain".into())],
|
||||
vec![],
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
async fn ws_handler(mut ws: WebSocket, state: Arc<State>) {
|
||||
let mut rx = state.tx.subscribe();
|
||||
while tokio::select! {
|
||||
_ = ws.recv() => return,
|
||||
fs_reload_event = rx.recv() => fs_reload_event.is_ok(),
|
||||
} {
|
||||
let ws_send = ws.send(axum::extract::ws::Message::Text(
|
||||
r#"{"reload": true}"#.to_owned(),
|
||||
));
|
||||
if ws_send.await.is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user