diff --git a/.github/workflows/test-cta.yml b/.github/workflows/test-cta.yml index 9e723d752..8e34ba871 100644 --- a/.github/workflows/test-cta.yml +++ b/.github/workflows/test-cta.yml @@ -26,7 +26,7 @@ jobs: matrix: node: ["14", "16"] manager: ["6", "7"] - recipe: ["vanillajs", "cra", "vite", "ngcli", "svelte"] + recipe: ["vanillajs", "cra", "vite", "ngcli", "svelte", "dominator"] exclude: - node: "16" manager: "6" diff --git a/tooling/create-tauri-app/src/index.ts b/tooling/create-tauri-app/src/index.ts index 05213f648..4498a7a21 100644 --- a/tooling/create-tauri-app/src/index.ts +++ b/tooling/create-tauri-app/src/index.ts @@ -11,6 +11,7 @@ import { cra } from './recipes/react' import { vuecli } from './recipes/vue-cli' import { vanillajs } from './recipes/vanilla' import { vite } from './recipes/vite' +import { dominator } from './recipes/dominator' import { ngcli } from './recipes/ng-cli' import { svelte } from './recipes/svelte' import { install, checkPackageManager } from './dependency-manager' @@ -116,7 +117,15 @@ interface Responses { installApi: boolean } -const allRecipes: Recipe[] = [vanillajs, cra, vite, vuecli, ngcli, svelte] +const allRecipes: Recipe[] = [ + vanillajs, + cra, + vite, + vuecli, + ngcli, + svelte, + dominator +] const recipeByShortName = (name: string): Recipe | undefined => allRecipes.find((r) => r.shortName === name) diff --git a/tooling/create-tauri-app/src/recipes/dominator.ts b/tooling/create-tauri-app/src/recipes/dominator.ts new file mode 100644 index 000000000..799c5ee88 --- /dev/null +++ b/tooling/create-tauri-app/src/recipes/dominator.ts @@ -0,0 +1,58 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import { join } from 'path' +// @ts-expect-error +import scaffe from 'scaffe' +import { Recipe } from '../types/recipe' + +export const dominator: Recipe = { + descriptiveName: { + name: 'Dominator (https://crates.io/crates/dominator/)', + value: 'Dominator' + }, + shortName: 'dominator', + configUpdate: ({ cfg, packageManager }) => ({ + ...cfg, + distDir: `../dist`, + devPath: 'http://localhost:10001/', + beforeDevCommand: `${packageManager === 'yarn' ? 'yarn' : 'npm run'} start`, + beforeBuildCommand: `${ + packageManager === 'yarn' ? 'yarn' : 'npm run' + } build` + }), + extraNpmDevDependencies: [], + extraNpmDependencies: [], + preInit: async ({ cwd, cfg }) => { + const { appName, windowTitle } = cfg + const templateDir = join(__dirname, '../src/templates/dominator') + const variables = { + name: appName, + title: windowTitle + } + + try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + await scaffe.generate(templateDir, join(cwd, appName), { + overwrite: true, + variables + }) + } catch (err) { + console.log(err) + } + }, + postInit: async ({ cfg, packageManager }) => { + console.log(` + Your installation completed. + + $ cd ${cfg.appName}. + $ ${packageManager} install + $ ${packageManager === 'yarn' ? 'yarn' : 'npm run'} tauri ${ + packageManager === 'npm' ? '--' : '' + } dev + + `) + return await Promise.resolve() + } +} diff --git a/tooling/create-tauri-app/src/templates/dominator/_.gitignore b/tooling/create-tauri-app/src/templates/dominator/_.gitignore new file mode 100644 index 000000000..5008655a9 --- /dev/null +++ b/tooling/create-tauri-app/src/templates/dominator/_.gitignore @@ -0,0 +1,5 @@ +node_modules +/dist/js +/target +/wasm-pack.log +/yarn-error.log diff --git a/tooling/create-tauri-app/src/templates/dominator/_Cargo.toml b/tooling/create-tauri-app/src/templates/dominator/_Cargo.toml new file mode 100644 index 000000000..d0ffcf899 --- /dev/null +++ b/tooling/create-tauri-app/src/templates/dominator/_Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "<%= name %>" +version = "1.0.0" +categories = ["wasm"] +edition = "2018" + +[profile.release] +lto = true + +[lib] +crate-type = ["cdylib"] + +[workspace] +members = [ + "src-tauri" +] + +[dependencies] +console_error_panic_hook = "0.1.6" +dominator = "0.5.17" +wasm-bindgen = "0.2.74" +futures-signals = "0.3.20" +once_cell = "1.7.2" diff --git a/tooling/create-tauri-app/src/templates/dominator/_package.json b/tooling/create-tauri-app/src/templates/dominator/_package.json new file mode 100644 index 000000000..4c7dc31df --- /dev/null +++ b/tooling/create-tauri-app/src/templates/dominator/_package.json @@ -0,0 +1,16 @@ +{ + "name": "<%= name %>", + "scripts": { + "tauri": "tauri", + "build": "rimraf dist/js && rollup --config", + "start": "rimraf dist/js && rollup --config --watch" + }, + "devDependencies": { + "@wasm-tool/rollup-plugin-rust": "^1.0.6", + "rimraf": "^3.0.2", + "rollup": "^2.50.2", + "rollup-plugin-livereload": "^2.0.0", + "rollup-plugin-serve": "^1.1.0", + "rollup-plugin-terser": "^7.0.2" + } +} diff --git a/tooling/create-tauri-app/src/templates/dominator/dist/_index.html b/tooling/create-tauri-app/src/templates/dominator/dist/_index.html new file mode 100644 index 000000000..15d374677 --- /dev/null +++ b/tooling/create-tauri-app/src/templates/dominator/dist/_index.html @@ -0,0 +1,27 @@ + + + + + <%= title %> + + + +

<%= name %>

+ + + diff --git a/tooling/create-tauri-app/src/templates/dominator/rollup.config.js b/tooling/create-tauri-app/src/templates/dominator/rollup.config.js new file mode 100644 index 000000000..09ffd2894 --- /dev/null +++ b/tooling/create-tauri-app/src/templates/dominator/rollup.config.js @@ -0,0 +1,32 @@ +import rust from '@wasm-tool/rollup-plugin-rust' +import serve from 'rollup-plugin-serve' +import livereload from 'rollup-plugin-livereload' +import { terser } from 'rollup-plugin-terser' + +const is_watch = !!process.env.ROLLUP_WATCH + +export default { + input: { + index: './Cargo.toml' + }, + output: { + dir: 'dist/js', + format: 'iife', + sourcemap: true + }, + plugins: [ + rust({ + serverPath: 'js/' + }), + + is_watch && + serve({ + contentBase: 'dist', + open: true + }), + + is_watch && livereload('dist'), + + !is_watch && terser() + ] +} diff --git a/tooling/create-tauri-app/src/templates/dominator/src/lib.rs b/tooling/create-tauri-app/src/templates/dominator/src/lib.rs new file mode 100644 index 000000000..9811f6050 --- /dev/null +++ b/tooling/create-tauri-app/src/templates/dominator/src/lib.rs @@ -0,0 +1,52 @@ +use wasm_bindgen::prelude::*; +use std::sync::Arc; +use once_cell::sync::Lazy; +use futures_signals::signal::{Mutable, SignalExt}; +use dominator::{Dom, html, class, clone, events}; + + +#[derive(Debug)] +struct App { + message: Mutable, +} + +impl App { + fn new() -> Arc { + Arc::new(Self { + message: Mutable::new("Hello world!".to_string()), + }) + } + + fn render(app: Arc) -> Dom { + // Define CSS styles + static CLASS: Lazy = Lazy::new(|| class! { + .style("font-size", "20px") + .style("color", "hsl(110, 70%, 70%)") + }); + + // Create the DOM nodes + html!("div", { + .class(&*CLASS) + + .text_signal(app.message.signal_cloned().map(|message| { + format!("Message: {}", message) + })) + + .event(clone!(app => move |_: events::Click| { + app.message.set_neq("Goodbye!".to_string()); + })) + }) + } +} + + +#[wasm_bindgen(start)] +pub fn main_js() -> Result<(), JsValue> { + #[cfg(debug_assertions)] + console_error_panic_hook::set_once(); + + let app = App::new(); + dominator::append_dom(&dominator::body(), App::render(app)); + + Ok(()) +} diff --git a/tooling/create-tauri-app/test/index.spec.ts b/tooling/create-tauri-app/test/index.spec.ts index e05b4c55e..082c4fdcd 100644 --- a/tooling/create-tauri-app/test/index.spec.ts +++ b/tooling/create-tauri-app/test/index.spec.ts @@ -15,7 +15,7 @@ const api = path.resolve('../api/') const manager = process.env.TAURI_RUN_MANAGER ?? 'npm' const recipes = process.env.TAURI_RECIPE ? [process.env.TAURI_RECIPE] - : ['vanillajs', 'cra', 'vite', 'vuecli', 'ngcli', 'svelte'] + : ['vanillajs', 'cra', 'vite', 'vuecli', 'ngcli', 'svelte', 'dominator'] const timeoutLong = 900000 const timeoutLittleLonger = 930000 const logOut = false ? 'inherit' : 'pipe' @@ -149,6 +149,13 @@ describe('CTA', () => { tauri: 'tauri' }) ) + }, + dominator: () => { + expect(packageFileOutput['scripts']).toEqual( + expect.objectContaining({ + tauri: 'tauri' + }) + ) } }