Jelajahi Sumber

chore: move CLI into its own "studio" app

Jonathan Kelley 4 tahun lalu
induk
melakukan
fd7933561f

+ 0 - 4
Cargo.toml

@@ -11,7 +11,6 @@ description = "Core functionality for Dioxus - a concurrent renderer-agnostic Vi
 dioxus-core = { path="./packages/core", version="0.1.0" }
 dioxus-core-macro = { path="./packages/core-macro", version="0.1.0" }
 dioxus-html-namespace = { path="./packages/html-namespace" }
-
 dioxus-web = { path="./packages/web", optional=true }
 # dioxus-hooks = { path="./packages/hooks", version="0.0.0" }
 
@@ -48,10 +47,7 @@ members = [
     "packages/html-namespace",
     "packages/web",
     "packages/webview",
-    "packages/cli",
     # "packages/atoms",
     # "packages/ssr",
     # "packages/docsite",
-    # "packages/router",
-    # "packages/inputs",
 ]

+ 0 - 2
packages/cli/.gitignore

@@ -1,2 +0,0 @@
-/target
-Cargo.lock

+ 0 - 3
packages/cli/.vscode/settings.json

@@ -1,3 +0,0 @@
-{
-    "rust-analyzer.inlayHints.enable": false
-}

+ 0 - 33
packages/cli/Cargo.toml

@@ -1,33 +0,0 @@
-[package]
-name = "dioxus-cli"
-version = "0.1.0"
-authors = ["Jonathan Kelley <jkelleyrtp@gmail.com>"]
-edition = "2018"
-description = "CLI tool for developing, testing, and publishing Dioxus apps"
-"license" = "MIT/Apache-2.0"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-thiserror = "1.0.23"
-log = "0.4.13"
-fern = { version="0.6.0", features=["colored"] }
-wasm-bindgen-cli-support = "0.2.73"
-anyhow = "1.0.38"
-argh = "0.1.4"
-serde = "1.0.120"
-serde_json = "1.0.61"
-async-std = { version="1.9.0", features=["attributes"] }
-tide = "0.15.0"
-fs_extra = "1.2.0"
-
-cargo_toml = "0.8.1"
-futures = "0.3.12"
-notify = "5.0.0-pre.4"
-rjdebounce = "0.2.1"
-tempfile = "3.2.0"
-
-[[bin]]
-
-path = "src/main.rs"
-name = "dioxus"

+ 0 - 48
packages/cli/README.md

@@ -1,48 +0,0 @@
-<div align="center">
-  <h1>📦✨  dioxus-cli</h1>
-  <p>
-    <strong>Tooling to supercharge dioxus projects</strong>
-  </p>
-</div>
-
-# About
----
-dioxus-cli (inspired by wasm-pack and webpack) is a tool to help get dioxus projects off the ground. It handles all the build, development, bundling, and publishing to make web development just a simple two commands: `cargo init` and `dioxus-cli publish`.
-
-Best thing: 
-- No NPM. 
-- No Webpack. 
-- No `node_modules`. 
-- No Babel
-- No parcel
-- No rollup
-- No ESLint
-
-Just install Rust, dioxus-cli, and you're good to go.
-`cargo install --git github.com/jkelleyrtp/dioxus-cli`
-
-Need a development server?
-`dioxus develop`
-
-Need to run an example?
-`dioxus develop --example textbox`
-
-Need to benchmark a component?
-`dioxus bench`
-
-Need to test your code?
-`dioxus test`
-
-Need to build your code into a bundle?
-`dioxus build --outdir public`
-
-Need to publish your code to GitHub pages, Netlify, etc?
-`dioxus publish --ghpages myrepo.git`
-
-# Use in your project
----
-Sometimes you'll want to include static assets without bundling them into your .wasm content. dioxus-cli provides a few ways of doing this:
-
-- Load in dynamic content using `dioxus::asset("./static/images/blah.svg")`
-- Live-reload HTML templates without rebuilding your .wasm with `dioxus::template("./templates/blah.html")`
-- Use a CSS library like tailwind in your dioxus configuration with

+ 0 - 146
packages/cli/src/builder.rs

@@ -1,146 +0,0 @@
-use crate::{
-    cli::BuildOptions,
-    config::{Config, ExecutableType},
-    error::Result,
-};
-use log::{info, warn};
-use std::{io::Write, process::Command};
-use wasm_bindgen_cli_support::Bindgen;
-
-pub struct BuildConfig {}
-impl Into<BuildConfig> for BuildOptions {
-    fn into(self) -> BuildConfig {
-        BuildConfig {}
-    }
-}
-impl Default for BuildConfig {
-    fn default() -> Self {
-        Self {}
-    }
-}
-
-pub fn build(config: &Config, _build_config: &BuildConfig) -> Result<()> {
-    /*
-    [1] Build the project with cargo, generating a wasm32-unknown-unknown target (is there a more specific, better target to leverage?)
-    [2] Generate the appropriate build folders
-    [3] Wasm-bindgen the .wasm fiile, and move it into the {builddir}/modules/xxxx/xxxx_bg.wasm
-    [4] Wasm-opt the .wasm file with whatever optimizations need to be done
-    [5] Link up the html page to the wasm module
-    */
-
-    let Config {
-        out_dir,
-        crate_dir,
-        target_dir,
-        static_dir,
-        executable,
-        ..
-    } = config;
-
-    let t_start = std::time::Instant::now();
-
-    // [1] Build the .wasm module
-    info!("Running build commands...");
-    let mut cmd = Command::new("cargo");
-    cmd.current_dir(&crate_dir)
-        .arg("build")
-        .arg("--target")
-        .arg("wasm32-unknown-unknown")
-        .stdout(std::process::Stdio::piped())
-        .stderr(std::process::Stdio::piped());
-
-    if config.release {
-        cmd.arg("--release");
-    }
-
-    match executable {
-        ExecutableType::Binary(name) => cmd.arg("--bin").arg(name),
-        ExecutableType::Lib(name) => cmd.arg("--lib").arg(name),
-        ExecutableType::Example(name) => cmd.arg("--example").arg(name),
-    };
-
-    let mut child = cmd.spawn()?;
-    let _err_code = child.wait()?;
-
-    info!("Build complete!");
-
-    // [2] Establish the output directory structure
-    let bindgen_outdir = out_dir.join("wasm");
-
-    // [3] Bindgen the final binary for use easy linking
-    let mut bindgen_builder = Bindgen::new();
-
-    let release_type = match config.release {
-        true => "release",
-        false => "debug",
-    };
-
-    let input_path = match executable {
-        ExecutableType::Binary(name) | ExecutableType::Lib(name) => target_dir
-            // .join("wasm32-unknown-unknown/release")
-            .join(format!("wasm32-unknown-unknown/{}", release_type))
-            .join(format!("{}.wasm", name)),
-
-        ExecutableType::Example(name) => target_dir
-            // .join("wasm32-unknown-unknown/release/examples")
-            .join(format!("wasm32-unknown-unknown/{}/examples", release_type))
-            .join(format!("{}.wasm", name)),
-    };
-
-    bindgen_builder
-        .input_path(input_path)
-        .web(true)?
-        .debug(true)
-        .demangle(true)
-        .keep_debug(true)
-        .remove_name_section(false)
-        .remove_producers_section(false)
-        .out_name("module")
-        .generate(&bindgen_outdir)?;
-
-    // [4]
-    // TODO: wasm-opt
-
-    // [5] Generate the html file with the module name
-    // TODO: support names via options
-    info!("Writing to '{:#?}' directory...", out_dir);
-    let mut file = std::fs::File::create(out_dir.join("index.html"))?;
-    file.write_all(gen_page("./wasm/module.js").as_str().as_bytes())?;
-
-    let copy_options = fs_extra::dir::CopyOptions::new();
-    match fs_extra::dir::copy(static_dir, out_dir, &copy_options) {
-        Ok(_) => {}
-        Err(_e) => {
-            warn!("Error copying dir");
-        }
-    }
-
-    let t_end = std::time::Instant::now();
-    log::info!("Done in {}ms! 🎉", (t_end - t_start).as_millis());
-    Ok(())
-}
-
-fn gen_page(module: &str) -> String {
-    format!(
-        r#"
-<html>
-  <head>
-    <meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
-    <meta charset="UTF-8" />
-    <link
-    href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css"
-    rel="stylesheet"
-    />
-  </head>
-  <body>
-    <!-- Note the usage of `type=module` here as this is an ES6 module -->
-    <script type="module">
-      import init from "{}";
-      init("./wasm/module_bg.wasm");
-    </script>
-  </body>
-</html>
-"#,
-        module
-    )
-}

+ 0 - 69
packages/cli/src/cargo.rs

@@ -1,69 +0,0 @@
-//! Utilities for working with cargo and rust files
-use crate::error::{Error, Result};
-use std::{env, fs, path::PathBuf, process::Command, str};
-
-/// How many parent folders are searched for a `Cargo.toml`
-const MAX_ANCESTORS: u32 = 10;
-
-/// Returns the root of the crate that the command is run from
-///
-/// If the command is run from the workspace root, this will return the top-level Cargo.toml
-pub fn crate_root() -> Result<PathBuf> {
-    // From the current directory we work our way up, looking for `Cargo.toml`
-    env::current_dir()
-        .ok()
-        .and_then(|mut wd| {
-            for _ in 0..MAX_ANCESTORS {
-                if contains_manifest(&wd) {
-                    return Some(wd);
-                }
-                if !wd.pop() {
-                    break;
-                }
-            }
-            None
-        })
-        .ok_or_else(|| Error::CargoError("Failed to find the cargo directory".to_string()))
-}
-
-/// Returns the root of a workspace
-/// TODO @Jon, find a different way that doesn't rely on the cargo metadata command (it's slow)
-pub fn workspace_root() -> Result<PathBuf> {
-    let output = Command::new("cargo")
-        .args(&["metadata"])
-        .output()
-        .map_err(|_| Error::CargoError("Manifset".to_string()))?;
-
-    if !output.status.success() {
-        let mut msg = str::from_utf8(&output.stderr).unwrap().trim();
-        if msg.starts_with("error: ") {
-            msg = &msg[7..];
-        }
-
-        return Err(Error::CargoError(msg.to_string()));
-    }
-
-    let stdout = str::from_utf8(&output.stdout).unwrap();
-    for line in stdout.lines() {
-        let meta: serde_json::Value = serde_json::from_str(line)
-            .map_err(|_| Error::CargoError("InvalidOutput".to_string()))?;
-
-        let root = meta["workspace_root"]
-            .as_str()
-            .ok_or_else(|| Error::CargoError("InvalidOutput".to_string()))?;
-        return Ok(root.into());
-    }
-
-    Err(Error::CargoError("InvalidOutput".to_string()))
-}
-
-/// Checks if the directory contains `Cargo.toml`
-fn contains_manifest(path: &PathBuf) -> bool {
-    fs::read_dir(path)
-        .map(|entries| {
-            entries
-                .filter_map(Result::ok)
-                .any(|ent| &ent.file_name() == "Cargo.toml")
-        })
-        .unwrap_or(false)
-}

+ 0 - 62
packages/cli/src/cli.rs

@@ -1,62 +0,0 @@
-use argh::FromArgs;
-
-#[derive(FromArgs, PartialEq, Debug)]
-/// Top-level command.
-pub struct LaunchOptions {
-    #[argh(subcommand)]
-    pub command: LaunchCommand,
-}
-
-/// The various kinds of commands that `wasm-pack` can execute.
-#[derive(FromArgs, PartialEq, Debug)]
-#[argh(subcommand)]
-pub enum LaunchCommand {
-    Develop(DevelopOptions),
-    Build(BuildOptions),
-    Test(TestOptions),
-    Publish(PublishOptions),
-}
-
-/// Publish your yew application to Github Pages, Netlify, or S3
-#[derive(FromArgs, PartialEq, Debug)]
-#[argh(subcommand, name = "publish")]
-pub struct PublishOptions {}
-
-/// 🔬 test your yew application!
-#[derive(FromArgs, PartialEq, Debug)]
-#[argh(subcommand, name = "test")]
-pub struct TestOptions {
-    /// an example in the crate
-    #[argh(option)]
-    pub example: Option<String>,
-}
-
-/// 🏗️  Build your yew application
-#[derive(FromArgs, PartialEq, Debug, Clone)]
-#[argh(subcommand, name = "build")]
-pub struct BuildOptions {
-    /// an optional direction which is "up" by default
-    #[argh(option, short = 'o', default = "String::from(\"public\")")]
-    pub outdir: String,
-
-    /// an example in the crate
-    #[argh(option)]
-    pub example: Option<String>,
-
-    /// develop in release mode
-    #[argh(switch, short = 'r')]
-    pub release: bool,
-}
-
-/// 🛠 Start a development server
-#[derive(FromArgs, PartialEq, Debug)]
-#[argh(subcommand, name = "develop")]
-pub struct DevelopOptions {
-    /// an example in the crate
-    #[argh(option)]
-    pub example: Option<String>,
-
-    /// develop in release mode
-    #[argh(switch, short = 'r')]
-    pub release: bool,
-}

+ 0 - 92
packages/cli/src/config.rs

@@ -1,92 +0,0 @@
-use crate::{
-    cli::{BuildOptions, DevelopOptions},
-    error::Result,
-};
-use std::{io::Write, path::PathBuf, process::Command};
-
-#[derive(Debug, Clone)]
-pub struct Config {
-    pub out_dir: PathBuf,
-    pub crate_dir: PathBuf,
-    pub workspace_dir: PathBuf,
-    pub target_dir: PathBuf,
-    pub static_dir: PathBuf,
-    pub manifest: cargo_toml::Manifest<cargo_toml::Value>,
-    pub executable: ExecutableType,
-    pub release: bool,
-}
-
-#[derive(Debug, Clone)]
-pub enum ExecutableType {
-    Binary(String),
-    Lib(String),
-    Example(String),
-}
-
-impl Config {
-    pub fn new() -> Result<Self> {
-        let crate_dir = crate::cargo::crate_root()?;
-        let workspace_dir = crate::cargo::workspace_root()?;
-        let target_dir = workspace_dir.join("target");
-        let out_dir = crate_dir.join("public");
-        let cargo_def = &crate_dir.join("Cargo.toml");
-        let static_dir = crate_dir.join("static");
-
-        let manifest = cargo_toml::Manifest::from_path(&cargo_def).unwrap();
-
-        // We just assume they're using a 'main.rs'
-        // Anyway, we've already parsed the manifest, so it should be easy to change the type
-        let output_filename = (&manifest)
-            .lib
-            .as_ref()
-            .and_then(|lib| lib.name.clone())
-            .or_else(|| {
-                (&manifest)
-                    .package
-                    .as_ref()
-                    .and_then(|pkg| Some(pkg.name.replace("-", "_")))
-                    .clone()
-            })
-            .expect("No lib found from cargo metadata");
-        let executable = ExecutableType::Binary(output_filename);
-
-        let release = false;
-
-        Ok(Self {
-            out_dir,
-            crate_dir,
-            workspace_dir,
-            target_dir,
-            static_dir,
-            manifest,
-            executable,
-            release,
-        })
-    }
-
-    pub fn as_example(&mut self, example_name: String) -> &mut Self {
-        self.executable = ExecutableType::Example(example_name);
-        self
-    }
-
-    pub fn with_release(&mut self, release: bool) -> &mut Self {
-        self.release = release;
-        self
-    }
-
-    pub fn with_build_options(&mut self, options: &BuildOptions) {
-        if let Some(name) = &options.example {
-            self.as_example(name.clone());
-        }
-        self.release = options.release;
-        self.out_dir = options.outdir.clone().into();
-    }
-
-    pub fn with_develop_options(&mut self, options: &DevelopOptions) {
-        if let Some(name) = &options.example {
-            self.as_example(name.clone());
-        }
-        self.release = options.release;
-        self.out_dir = tempfile::Builder::new().tempdir().expect("").into_path();
-    }
-}

+ 0 - 111
packages/cli/src/develop.rs

@@ -1,111 +0,0 @@
-use crate::{builder::BuildConfig, cli::DevelopOptions, config::Config, error::Result};
-use async_std::prelude::FutureExt;
-
-use async_std::future;
-use async_std::prelude::*;
-
-use log::info;
-use notify::{RecommendedWatcher, RecursiveMode, Watcher};
-use std::path::PathBuf;
-use std::time::Duration;
-
-pub struct DevelopConfig {}
-impl Into<DevelopConfig> for DevelopOptions {
-    fn into(self) -> DevelopConfig {
-        DevelopConfig {}
-    }
-}
-
-pub async fn start(config: &Config, _options: &DevelopConfig) -> Result<()> {
-    log::info!("Starting development server 🚀");
-
-    let Config { out_dir, .. } = config;
-
-    // Spawn the server onto a seperate task
-    // This lets the task progress while we handle file updates
-    let server = async_std::task::spawn(launch_server(out_dir.clone()));
-    let watcher = async_std::task::spawn(watch_directory(config.clone()));
-
-    match server.race(watcher).await {
-        Err(e) => log::warn!("Error running development server, {:?}", e),
-        _ => {}
-    }
-
-    Ok(())
-}
-
-async fn watch_directory(config: Config) -> Result<()> {
-    // Create a channel to receive the events.
-    let (watcher_tx, watcher_rx) = async_std::channel::bounded(100);
-
-    // Automatically select the best implementation for your platform.
-    // You can also access each implementation directly e.g. INotifyWatcher.
-    let mut watcher: RecommendedWatcher = Watcher::new_immediate(move |res| {
-        async_std::task::block_on(watcher_tx.send(res));
-    })
-    .expect("failed to make watcher");
-
-    let src_dir = crate::cargo::crate_root()?;
-
-    // Add a path to be watched. All files and directories at that path and
-    // below will be monitored for changes.
-    watcher
-        .watch(src_dir.join("src"), RecursiveMode::Recursive)
-        .expect("Failed to watch dir");
-
-    watcher
-        .watch(src_dir.join("examples"), RecursiveMode::Recursive)
-        .expect("Failed to watch dir");
-
-    let build_config = BuildConfig::default();
-
-    'run: loop {
-        crate::builder::build(&config, &build_config)?;
-
-        // Wait for the message with a debounce
-        let _msg = watcher_rx
-            .recv()
-            .join(future::ready(1_usize).delay(Duration::from_millis(2000)))
-            .await;
-
-        info!("File updated, rebuilding app");
-    }
-    Ok(())
-}
-
-async fn launch_server(outdir: PathBuf) -> Result<()> {
-    let _crate_dir = crate::cargo::crate_root()?;
-    let _workspace_dir = crate::cargo::workspace_root()?;
-
-    let mut app = tide::with_state(ServerState::new(outdir.to_owned()));
-    let p = outdir.display().to_string();
-
-    app.at("/")
-        .get(|req: tide::Request<ServerState>| async move {
-            log::info!("Connected to development server");
-            let state = req.state();
-            Ok(tide::Body::from_file(state.serv_path.clone().join("index.html")).await?)
-        })
-        .serve_dir(p)?;
-
-    let port = "8080";
-    let serve_addr = format!("0.0.0.0:{}", port);
-    // let serve_addr = format!("127.0.0.1:{}", port);
-
-    info!("App available at http://{}", serve_addr);
-    app.listen(serve_addr).await?;
-    Ok(())
-}
-
-/// https://github.com/http-rs/tide/blob/main/examples/state.rs
-/// Tide seems to prefer using state instead of injecting into the app closure
-/// The app closure needs to be static and
-#[derive(Clone)]
-struct ServerState {
-    serv_path: PathBuf,
-}
-impl ServerState {
-    fn new(serv_path: PathBuf) -> Self {
-        Self { serv_path }
-    }
-}

+ 0 - 34
packages/cli/src/error.rs

@@ -1,34 +0,0 @@
-use thiserror::Error as ThisError;
-
-pub type Result<T, E = Error> = std::result::Result<T, E>;
-
-#[derive(ThisError, Debug)]
-pub enum Error {
-    /// Used when errors need to propogate but are too unique to be typed
-    #[error("{0}")]
-    Unique(String),
-
-    #[error("I/O Error: {0}")]
-    IO(#[from] std::io::Error),
-
-    #[error("Failed to write error")]
-    FailedToWrite,
-
-    #[error("Failed to write error")]
-    CargoError(String),
-
-    #[error(transparent)]
-    Other(#[from] anyhow::Error),
-}
-
-impl From<&str> for Error {
-    fn from(s: &str) -> Self {
-        Error::Unique(s.to_string())
-    }
-}
-
-impl From<String> for Error {
-    fn from(s: String) -> Self {
-        Error::Unique(s)
-    }
-}

+ 0 - 8
packages/cli/src/lib.rs

@@ -1,8 +0,0 @@
-pub mod builder;
-pub mod cargo;
-pub mod cli;
-pub mod config;
-pub mod develop;
-pub mod error;
-pub mod logging;
-pub mod watch;

+ 0 - 49
packages/cli/src/logging.rs

@@ -1,49 +0,0 @@
-use fern::colors::{Color, ColoredLevelConfig};
-use log::debug;
-
-pub fn set_up_logging() {
-    // configure colors for the whole line
-    let colors_line = ColoredLevelConfig::new()
-        .error(Color::Red)
-        .warn(Color::Yellow)
-        // we actually don't need to specify the color for debug and info, they are white by default
-        .info(Color::White)
-        .debug(Color::White)
-        // depending on the terminals color scheme, this is the same as the background color
-        .trace(Color::BrightBlack);
-
-    // configure colors for the name of the level.
-    // since almost all of them are the same as the color for the whole line, we
-    // just clone `colors_line` and overwrite our changes
-    let colors_level = colors_line.clone().info(Color::Green);
-    // here we set up our fern Dispatch
-    fern::Dispatch::new()
-        .format(move |out, message, record| {
-            out.finish(format_args!(
-                "{color_line}[{level}{color_line}] {message}\x1B[0m",
-                color_line = format_args!(
-                    "\x1B[{}m",
-                    colors_line.get_color(&record.level()).to_fg_str()
-                ),
-                level = colors_level.color(record.level()),
-                message = message,
-            ));
-        })
-        // set the default log level. to filter out verbose log messages from dependencies, set
-        // this to Warn and overwrite the log level for your crate.
-        .level(log::LevelFilter::Info)
-        // .level(log::LevelFilter::Warn)
-        // change log levels for individual modules. Note: This looks for the record's target
-        // field which defaults to the module path but can be overwritten with the `target`
-        // parameter:
-        // `info!(target="special_target", "This log message is about special_target");`
-        // .level_for("dioxus", log::LevelFilter::Debug)
-        // .level_for("dioxus", log::LevelFilter::Info)
-        // .level_for("pretty_colored", log::LevelFilter::Trace)
-        // output to stdout
-        .chain(std::io::stdout())
-        .apply()
-        .unwrap();
-
-    debug!("finished setting up logging! yay!");
-}

+ 0 - 28
packages/cli/src/main.rs

@@ -1,28 +0,0 @@
-use diopack::cli::{LaunchCommand, LaunchOptions};
-use dioxus_cli as diopack;
-
-#[async_std::main]
-async fn main() -> diopack::error::Result<()> {
-    diopack::logging::set_up_logging();
-
-    let opts: LaunchOptions = argh::from_env();
-    let mut config = diopack::config::Config::new()?;
-
-    match opts.command {
-        LaunchCommand::Build(options) => {
-            config.with_build_options(&options);
-            diopack::builder::build(&config, &(options.into()))?;
-        }
-
-        LaunchCommand::Develop(options) => {
-            config.with_develop_options(&options);
-            diopack::develop::start(&config, &(options.into())).await?;
-        }
-
-        _ => {
-            todo!("Command not currently implemented");
-        }
-    }
-
-    Ok(())
-}

+ 0 - 11
packages/cli/src/watch.rs

@@ -1,11 +0,0 @@
-pub struct Watcher {}
-
-impl Watcher {
-    // Spawns a new notify instance that alerts us of changes
-    pub fn new() -> Self {
-        Self {}
-    }
-
-    /// Subsribe to the watcher
-    pub fn subscribe() {}
-}

+ 0 - 1
packages/core/src/hooks.rs

@@ -7,7 +7,6 @@
 
 use crate::innerlude::Context;
 
-use crate::innerlude::*;
 use std::{
     cell::RefCell,
     ops::{Deref, DerefMut},

+ 0 - 8
packages/inputs/Cargo.toml

@@ -1,8 +0,0 @@
-[package]
-name = "dioxus-inputs"
-version = "0.0.0"
-edition = "2018"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]

+ 0 - 28
packages/inputs/README.md

@@ -1,28 +0,0 @@
-# Cross-platform controlled inputs
-
-Dioxus does not include controlled inputs in Dioxus-Core. This would require core integration with HTML that is inherently not cross platform. Instead, this crate exists to provide a bunch of cross-platform input types that abstract over renderer quirks.
-
-Included is:
-
-- Button
-- Checkbox
-- Color
-- Date
-- Datetime-local
-- Email
-- File
-- Hidden
-- Image
-- Month
-- Number
-- Password
-- Radio
-- Range
-- Reset
-- Search
-- Submit
-- Tel
-- Text
-- Time
-- Url
-- Week

+ 0 - 7
packages/inputs/src/lib.rs

@@ -1,7 +0,0 @@
-#[cfg(test)]
-mod tests {
-    #[test]
-    fn it_works() {
-        assert_eq!(2 + 2, 4);
-    }
-}

+ 0 - 1
packages/liveview/.gitignore

@@ -1 +0,0 @@
-.vscode/

+ 0 - 39
packages/liveview/Cargo.toml

@@ -1,39 +0,0 @@
-[package]
-name = "dioxus-livehost"
-version = "0.0.0"
-authors = ["Jonathan Kelley <jkelleyrtp@gmail.com>"]
-edition = "2018"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-dioxus-core = { path = "../core", version = "0.1.2" }
-dioxus-web = { path = "../web" }
-
-
-serde = { version = "1", features = ['derive'] }
-tide = "0.16.0"
-tide-websockets = "0.3.0"
-async-std = { version = "1.8.0", features = ["attributes"] }
-log = "0.4"
-fern = { version = "0.6.0", features = ["colored"] }
-async-channel = "1.5.1"
-futures-lite = "1.11.2"
-anyhow = "1.0.35"
-
-
-js-sys = { version = "0.3", optional = true }
-wasm-bindgen = { version = "0.2.71", optional = true }
-lazy_static = { version = "1.4.0", optional = true }
-wasm-bindgen-futures = { version = "0.4.20", optional = true }
-
-
-serde_millis = "0.1"
-serde_json = "1"
-strum = { version = "0.20", features = ["derive"] }
-
-
-[features]
-default = ["client", "server"]
-server = []
-client = []

+ 0 - 13
packages/liveview/README.md

@@ -1,13 +0,0 @@
-# Livehost
-
-Stream events from a server to a client.
-
-This crate provides drivers for Actix, Warp, and Tide to run coupled frontend and backend. 
-
-This comes in the form of two approaches:
-
-- tight coupling: frontend and backend are locked together
-- loose coupling: hooks subscribe a component to a server using the suspense mechanism
-
-Tight coupling is basically an implmentation of loose coupling where **all** events move through the backend connection. This coupling option has higher latency but is very simple to deploy. We use this approach for dioxus-webview where latency is minimal (hosted locally) and we want builds to be simple - no need to manually bundle a custom frontend because everything is server rendered.
-

+ 0 - 131
packages/liveview/examples/simpletide.rs

@@ -1,131 +0,0 @@
-pub fn main() {
-    #[cfg(feature = "client")]
-    wasm_bindgen_futures::spawn_local(async { client::app().await.unwrap() });
-
-    #[cfg(feature = "server")]
-    async_std::task::block_on(async { server::app().await.expect("") });
-}
-
-/// ===============================
-///  Common code (shared types)
-/// ===============================
-#[derive(PartialEq, strum::EnumIter, strum::Display, strum::AsRefStr, strum::EnumString)]
-pub enum SelectedStream {
-    Football,
-    Hockey,
-    Socker,
-}
-
-/// Client-specific code
-#[cfg(feature = "client")]
-mod client {
-    use super::*;
-    use dioxus_core::prelude::*;
-    use strum::IntoEnumIterator;
-
-    pub async fn app() -> anyhow::Result<()> {
-        Ok(dioxus_web::WebsysRenderer::start(APP).await)
-    }
-
-    static APP: FC<()> = |cx| {
-        todo!()
-        // let (selected_stream, set_stream) = use_state(cx, || SelectedStream::Football);
-
-        // let opts = SelectedStream::iter().map(|name| rsx! { option { "{name}", value: "{name}" } });
-
-        // cx.render(rsx! {
-        //     div {
-        //         h1 { "Tide basic CRUD app" }
-        //         h2 { "Chosen stream: {selected_stream}" }
-        //         select {
-        //             value: {selected_stream.as_ref()}
-        //             "{selected_stream}"
-        //             {opts}
-        //         }
-        //     }
-        // })
-    };
-}
-
-/// Server-specific code
-#[cfg(feature = "server")]
-mod server {
-    use async_std::sync::RwLock;
-    pub use log::info;
-    use std::sync::Arc;
-    use tide::Request;
-    use tide_websockets::{Message, WebSocket, WebSocketConnection};
-
-    use crate::SelectedStream;
-
-    // type ServerRequest = Request<Arc<RwLock<()>>>;
-    type ServerRequest = Request<()>;
-    // type ServerRequest = Request<Arc<RwLock<ServerState>>>;
-
-    static CLIENT_PATH: &'static str = "";
-
-    pub async fn app() -> anyhow::Result<()> {
-        let mut app = tide::new();
-
-        app.at("")
-            .serve_dir(format!("{}/pkg", CLIENT_PATH))
-            .expect("Cannot serve directory");
-
-        app.at("/updates").get(WebSocket::new(socket_handler));
-
-        let addr = "0.0.0.0:9001";
-        log::info!("Congrats! Server is up and running at http://{}", addr);
-        app.listen(addr).await?;
-
-        Ok(())
-    }
-
-    async fn socket_handler(
-        request: ServerRequest,
-        stream: WebSocketConnection,
-    ) -> tide::Result<()> {
-        // clone the receiver channel
-        // subscribe to any updates
-        // let receiver = request.state().read().await.receiver.clone();
-        // while let Ok(evt) = receiver.recv().await {
-        //     let response_msg = serde_json::to_string(&evt)?;
-        //     stream.send_string(response_msg).await?;
-        // }
-
-        Ok(())
-    }
-
-    use dioxus_core::prelude::*;
-
-    #[derive(PartialEq, Props)]
-    struct SreamListProps {
-        selected_stream: SelectedStream,
-    }
-
-    static STREAM_LIST: FC<SreamListProps> = |cx| {
-        //
-        let g = match cx.selected_stream {
-            SelectedStream::Football => cx.render(rsx! {
-                li {
-                    "watch football!"
-                }
-            }),
-            SelectedStream::Hockey => cx.render(rsx! {
-                li {
-                    "watch football!"
-                }
-            }),
-            SelectedStream::Socker => cx.render(rsx! {
-                li {
-                    "watch football!"
-                }
-            }),
-        };
-
-        cx.render(rsx! {
-            div {
-
-            }
-        })
-    };
-}

+ 0 - 182
packages/liveview/examples/tide.rs

@@ -1,182 +0,0 @@
-pub fn main() {
-    #[cfg(feature = "client")]
-    wasm_bindgen_futures::spawn_local(async { client::app().await.unwrap() });
-
-    #[cfg(feature = "server")]
-    async_std::task::block_on(async { server::app().await.expect("") });
-}
-
-/// ===============================
-///  Common code (shared types)
-/// ===============================
-#[derive(PartialEq, strum::EnumIter, strum::Display, strum::AsRefStr, strum::EnumString)]
-pub enum SelectedStream {
-    Football,
-    Hockey,
-    Socker,
-}
-
-/// Client-specific code
-#[cfg(feature = "client")]
-mod client {
-    use super::*;
-    use dioxus_core::prelude::*;
-    use strum::IntoEnumIterator;
-
-    pub async fn app() -> anyhow::Result<()> {
-        Ok(dioxus_web::WebsysRenderer::start(APP).await)
-    }
-
-    static APP: FC<()> = |cx| {
-        todo!()
-        // let (selected_stream, set_stream) = use_state(cx, || SelectedStream::Football);
-
-        // let opts = SelectedStream::iter().map(|name| rsx! { option { "{name}", value: "{name}" } });
-
-        // cx.render(rsx! {
-        //     div {
-        //         h1 { "Tide basic CRUD app" }
-        //         h2 { "Chosen stream: {selected_stream}" }
-        //         select {
-        //             value: {selected_stream.as_ref()}
-        //             "{selected_stream}"
-        //             {opts}
-        //         }
-        //     }
-        // })
-    };
-}
-
-/// Server-specific code
-#[cfg(feature = "server")]
-mod server {
-    use async_std::sync::RwLock;
-    pub use log::info;
-    use std::sync::Arc;
-    use tide::Request;
-    use tide_websockets::{Message, WebSocket, WebSocketConnection};
-
-    use crate::SelectedStream;
-
-    // type ServerRequest = Request<Arc<RwLock<()>>>;
-    type ServerRequest = Request<()>;
-    // type ServerRequest = Request<Arc<RwLock<ServerState>>>;
-
-    static CLIENT_PATH: &'static str = "";
-
-    pub async fn app() -> anyhow::Result<()> {
-        let mut app = tide::new();
-
-        app.at("")
-            .serve_dir(format!("{}/pkg", CLIENT_PATH))
-            .expect("Cannot serve directory");
-
-        app.at("/updates").get(WebSocket::new(socket_handler));
-
-        let addr = "0.0.0.0:9001";
-        log::info!("Congrats! Server is up and running at http://{}", addr);
-        app.listen(addr).await?;
-
-        Ok(())
-    }
-
-    async fn socket_handler(
-        request: ServerRequest,
-        stream: WebSocketConnection,
-    ) -> tide::Result<()> {
-        // clone the receiver channel
-        // subscribe to any updates
-        // let receiver = request.state().read().await.receiver.clone();
-        // while let Ok(evt) = receiver.recv().await {
-        //     let response_msg = serde_json::to_string(&evt)?;
-        //     stream.send_string(response_msg).await?;
-        // }
-
-        Ok(())
-    }
-
-    use dioxus_core::prelude::*;
-
-    #[derive(PartialEq, Props)]
-    struct SreamListProps {
-        selected_stream: SelectedStream,
-    }
-
-    static STREAM_LIST: FC<SreamListProps> = |cx| {
-        //
-        match cx.selected_stream {
-            SelectedStream::Football => cx.render(rsx! {
-                li {
-                    "watch football!"
-                }
-            }),
-
-            _ => unimplemented!()
-            // .render(cx),
-            // SelectedStream::Hockey => rsx! {
-            //     li {
-            //         "watch football!"
-            //     }
-            // }
-            // .render(cx),
-            // SelectedStream::Socker => rsx! {
-            //     li {
-            //         "watch football!"
-            //     }
-            // }
-            // .render(cx),
-        }
-    };
-}
-
-mod ergorsx {
-
-    // struct Ncx {}
-
-    // struct VVNode {}
-    // struct DTree {
-    //     // struct DTree<F: Fn(&Ncx) -> VVNode> {
-    //     caller: F,
-    // }
-    // impl<F: Fn(&Ncx) -> VVNode> DTree<F> {
-    //     fn new(f: F) -> Self {
-    //         Self { caller: f }
-    //     }
-    // }
-
-    // trait Renderable {
-    //     fn render(self, nodecx: &Ncx) -> VVNode;
-    // }
-
-    // impl<F: Fn(&Ncx) -> VVNode> Renderable for DTree<F> {
-    //     fn render(self, nodecx: &Ncx) -> VVNode {
-    //         (self.caller)(nodecx)
-    //     }
-    // }
-
-    // fn test() {
-    //     let t = 123;
-    //     let r = match t {
-    //         123 => DTree::new(|f| VVNode {}).render(cx),
-    //         456 => DTree::new(|f| VVNode {}).render(cx),
-    //         789 => DTree::new(|f| VVNode {}).render(cx),
-    //         _ => unreachable!(),
-    //     };
-    // }
-
-    // fn example() {
-    //     rsx! {
-    //         div {
-
-    //         }
-    //     }.render(cx)
-    // }
-
-    // fn example() {
-    //     cx.render(rsx!{
-    //         div {
-
-    //         }
-    //     })
-    // }
-}

+ 0 - 294
packages/liveview/index.html

@@ -1,294 +0,0 @@
-<!-- a js-only interpreter for the dioxus patch stream :) -->
-<!DOCTYPE html>
-<html>
-  <head>
-    <meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
-    <meta charset="UTF-8" />
-    <link
-      href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css"
-      rel="stylesheet"
-    />
-  </head>
-  <body>
-    <div></div>
-  </body>
-  <script>
-    class Interpreter {
-      constructor(root) {
-        this.stack = [root];
-      }
-
-      top() {
-        return this.stack[this.stack.length - 1];
-      }
-
-      pop() {
-        return this.stack.pop();
-      }
-    }
-
-    class OPTABLE {
-      // 0
-      SetText(edit, interp) {
-        interp.top(interp.stack).textContent = edit.text;
-      }
-      // 1
-      RemoveSelfAndNextSiblings(edit) {
-        const node = interp.pop();
-        let sibling = node.nextSibling;
-        while (sibling) {
-          const temp = sibling.nextSibling;
-          sibling.remove();
-          sibling = temp;
-        }
-        node.remove();
-      }
-
-      // 2
-      ReplaceWith(edit, interp) {
-        const newNode = interp.pop();
-        const oldNode = interp.pop();
-        oldNode.replaceWith(newNode);
-        interp.stack.push(newNode);
-      }
-
-      // 3
-      SetAttribute(edit, interp) {
-        const name = edit.name;
-        const value = edit.value;
-        const node = interp.top(interp.stack);
-        node.setAttribute(name, value);
-
-        // Some attributes are "volatile" and don't work through `setAttribute`.
-        if ((name === "value", interp)) {
-          node.value = value;
-        }
-        if ((name === "checked", interp)) {
-          node.checked = true;
-        }
-        if ((name === "selected", interp)) {
-          node.selected = true;
-        }
-      }
-
-      // 4
-      RemoveAttribute(edit, interp) {
-        const name = edit.name;
-        const node = interp.top(interp.stack);
-        node.removeAttribute(name);
-
-        // Some attributes are "volatile" and don't work through `removeAttribute`.
-        if ((name === "value", interp)) {
-          node.value = null;
-        }
-        if ((name === "checked", interp)) {
-          node.checked = false;
-        }
-        if ((name === "selected", interp)) {
-          node.selected = false;
-        }
-      }
-
-      // 5
-      PushReverseChild(edit, interp) {
-        const n = edit.n;
-        const parent = interp.top(interp.stack);
-        const children = parent.childNodes;
-        const child = children[children.length - n - 1];
-        interp.stack.push(child);
-      }
-
-      // 6
-      PopPushChild(edit, interp) {
-        const n = edit.n;
-        interp.pop();
-        const parent = interp.top(interp.stack);
-        const children = parent.childNodes;
-        const child = children[n];
-        interp.stack.push(child);
-      }
-
-      // 7
-      Pop(edit, interp) {
-        interp.pop();
-      }
-
-      // 8
-      AppendChild(edit, interp) {
-        console.log(interp.stack);
-        const child = interp.pop();
-        console.log(interp.stack);
-        interp.top().appendChild(child);
-      }
-
-      // 9
-      CreateTextNode(edit, interp) {
-        // interp.stack.push(document.createTextNode("asd"));
-        console.log(interp.stack);
-
-        interp.stack.push(document.createTextNode(edit.text));
-        console.log(interp.stack);
-      }
-
-      // 10
-      CreateElement(edit, interp) {
-        const tagName = edit.tag_name;
-        interp.stack.push(document.createElement(tagName));
-      }
-
-
-
-      // 11
-      NewEventListener(edit, interp) {
-        // todo!
-        const eventId = mem32[i++];
-        const eventType = interp.getCachedString(eventId);
-        const a = mem32[i++];
-        const b = mem32[i++];
-        const el = interp.top(interp.stack);
-        el.addEventListener(eventType, interp.eventHandler);
-        el[`dodrio-a-${eventType}`] = a;
-        el[`dodrio-b-${eventType}`] = b;
-      }
-
-      // 12
-      UpdateEventListener(edit, interp) {
-        // todo!
-        const eventId = mem32[i++];
-        const eventType = interp.getCachedString(eventId);
-        const el = interp.top(interp.stack);
-        el[`dodrio-a-${eventType}`] = mem32[i++];
-        el[`dodrio-b-${eventType}`] = mem32[i++];
-      }
-
-      // 13
-      RemoveEventListener(edit, interp) {
-        // todo!
-        const eventId = mem32[i++];
-        const eventType = interp.getCachedString(eventId);
-        const el = interp.top(interp.stack);
-        el.removeEventListener(eventType, interp.eventHandler);
-      }
-
-      // 14
-      AddCachedString(edit, interp) {
-        // todo!
-        const pointer = mem32[i++];
-        const length = mem32[i++];
-        const id = mem32[i++];
-        const str = string(mem8, pointer, length);
-        interp.addCachedString(str, id);
-      }
-
-      // 15
-      DropCachedString(edit, interp) {
-        // todo!
-        const id = mem32[i++];
-        interp.dropCachedString(id);
-      }
-
-      // 16
-      CreateElementNs(edit, interp) {
-        //   const tagNameId = mem32[i++];
-        //   const tagName = interp.getCachedString(tagNameId);
-        //   const nsId = mem32[i++];
-        //   const ns = interp.getCachedString(nsId);
-        interp.stack.push(document.createElementNS(edit.ns, edit.tag_name));
-      }
-
-      // 17
-      SaveChildrenToTemporaries(edit, interp) {
-        //   let temp = mem32[i++];
-        //   const start = mem32[i++];
-        //   const end = mem32[i++];
-        let temp = edit.temp;
-        const start = edit.start;
-        const end = edit.end;
-        const parent = interp.top(interp.stack);
-        const children = parent.childNodes;
-        for (let i = start; i < end; i++, interp) {
-          interp.temporaries[temp++] = children[i];
-        }
-      }
-
-      // 18
-      PushChild(edit, interp) {
-        const parent = interp.top(interp.stack);
-        //   const n = mem32[i++];
-        const n = edit.n;
-        const child = parent.childNodes[n];
-        interp.stack.push(child);
-      }
-
-      // 19
-      PushTemporary(edit, interp) {
-        //   const temp = mem32[i++];
-        const temp = edit.temp;
-        interp.stack.push(interp.temporaries[temp]);
-      }
-
-      // 20
-      InsertBefore(edit, interp) {
-        const before = interp.pop();
-        const after = interp.pop();
-        after.parentNode.insertBefore(before, after);
-        interp.stack.push(before);
-      }
-
-      // 21
-      PopPushReverseChild(edit, interp) {
-        //   const n = mem32[i++];
-        const n = edit.n;
-        interp.pop();
-        const parent = interp.top(interp.stack);
-        const children = parent.childNodes;
-        const child = children[children.length - n - 1];
-        interp.stack.push(child);
-      }
-
-      // 22
-      RemoveChild(edit, interp) {
-        //   const n = mem32[i++];
-        const n = edit.n;
-        const parent = interp.top(interp.stack);
-        const child = parent.childNodes[n];
-        child.remove();
-      }
-
-      // 23
-      SetClass(edit, interp) {
-        //   const classId = mem32[i++];
-        const className = edit.class_name;
-        interp.top(interp.stack).className = className;
-      }
-
-      // 24
-      SaveTemplate(edit, interp) {
-        const id = mem32[i++];
-        const template = interp.top(interp.stack);
-        interp.saveTemplate(id, template.cloneNode(true));
-      }
-
-      // 25
-      PushTemplate(edit, interp) {
-        const id = mem32[i++];
-        const template = interp.getTemplate(id);
-        interp.stack.push(template.cloneNode(true));
-      }
-    }
-
-    const op_table = new OPTABLE();
-    const interpreter = new Interpreter(window.document.body);
-
-    function EditListReceived(rawEditList) {
-      let editList = JSON.parse(rawEditList);
-      console.warn("hnelllo");
-      editList.forEach(function (edit, index) {
-        console.log(edit);
-        op_table[edit.type](edit, interpreter);
-      });
-    }
-
-    external.invoke("initiate");
-  </script>
-</html>

+ 0 - 1
packages/liveview/src/handlers/h_actix.rs

@@ -1 +0,0 @@
-//! Request handler for actix

+ 0 - 1
packages/liveview/src/handlers/h_rocket.rs

@@ -1 +0,0 @@
-//! Request handler for rocket

+ 0 - 1
packages/liveview/src/handlers/h_tide.rs

@@ -1 +0,0 @@
-//! Request handler for tide

+ 0 - 1
packages/liveview/src/handlers/h_warp.rs

@@ -1 +0,0 @@
-//! Request handler for warp

+ 0 - 10
packages/liveview/src/lib.rs

@@ -1,10 +0,0 @@
-mod handlers {
-
-    pub mod h_actix;
-
-    pub mod h_rocket;
-
-    pub mod h_tide;
-
-    pub mod h_warp;
-}

+ 0 - 0
packages/ios/Cargo.toml → packages/mobile/Cargo.toml


+ 0 - 0
packages/ios/README.md → packages/mobile/README.md


+ 0 - 0
packages/ios/src/lib.rs → packages/mobile/src/lib.rs


+ 0 - 9
packages/router/Cargo.toml

@@ -1,9 +0,0 @@
-[package]
-name = "dioxus-router"
-version = "0.0.0"
-authors = ["Jonathan Kelley <jkelleyrtp@gmail.com>"]
-edition = "2018"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]

+ 0 - 40
packages/router/README.md

@@ -1,40 +0,0 @@
-# Router hook for Dioxus apps
-
-Dioxus-router provides a use_router hook that returns a different value depending on the route.
-The router is generic over any value, however it makes sense to return a different set of VNodes
-and feed them into the App's return VNodes.
-
-Using the router should feel similar to tide's routing framework where an "address" book is assembled at the head of the app.
-
-Here's an example of how to use the router hook:
-
-```rust
-static App: FC<()> = |cx| {
-
-    // Route returns the associated VNodes
-    // This hook re-fires when the route changes
-    let route = use_router(cx, |router| {
-        router.at("/").get(|path| {
-            rsx!{ <LandingPage /> }
-        });
-        router.at("/shoes/:id").get(|path| {
-            let id: Uuid = path.parse().unwrap();
-            rsx!{ <ShoesPage id=id /> }
-        });
-        router.at("/pants/:id").get(|path| {
-            let id: Uuid = path.parse().unwrap();
-            rsx!{ <PantsPage id=id /> }
-        });
-    });
-
-    cx.render(rsx!{
-        div {
-            Navbar {}
-            {route}
-            Footer {}
-        }
-    })
-};
-```
-
-Currently, the router is only supported in a web environment, but we plan to add 1st-party support via the context API when new renderers are available.

+ 0 - 7
packages/router/src/lib.rs

@@ -1,7 +0,0 @@
-#[cfg(test)]
-mod tests {
-    #[test]
-    fn it_works() {
-        assert_eq!(2 + 2, 4);
-    }
-}

+ 0 - 7
src/lib.rs

@@ -218,10 +218,3 @@ pub mod testing {
 }
 #[cfg(feature = "atoms")]
 pub mod atoms {}
-
-// #[cfg(feature = "desktop")]
-pub mod webview {
-    //! A webview based renderer for building desktop applications with Dioxus
-    use dioxus_core::prelude::{Properties, FC};
-    pub fn launch<P: Properties>(f: FC<P>) {}
-}