├── src ├── definitions │ ├── vite-env.d.ts │ ├── env.d.ts │ ├── src-wasm.d.ts │ ├── shims-vue.d.ts │ ├── shims-app.d.ts │ └── getContextValues.d.ts ├── assets │ └── logo.png ├── components │ ├── HelloTsx.tsx │ ├── Add.tsx │ └── HelloWorld.vue ├── main.ts └── App.vue ├── src-go ├── go.mod └── main.go ├── Cargo.toml ├── public └── favicon.ico ├── src-tauri ├── icons │ ├── icon.ico │ ├── icon.png │ ├── 32x32.png │ ├── icon.icns │ ├── 128x128.png │ ├── StoreLogo.png │ ├── 128x128@2x.png │ ├── Square30x30Logo.png │ ├── Square44x44Logo.png │ ├── Square71x71Logo.png │ ├── Square89x89Logo.png │ ├── Square107x107Logo.png │ ├── Square142x142Logo.png │ ├── Square150x150Logo.png │ ├── Square284x284Logo.png │ └── Square310x310Logo.png ├── .gitignore ├── rustfmt.toml ├── src │ ├── build.rs │ ├── cmd.rs │ └── main.rs ├── Cargo.toml └── tauri.conf.json ├── lint-staged.config.cjs ├── index.html ├── Makefile ├── tsconfig.json ├── .github └── workflows │ ├── clean-workflow.yml │ └── release.yml ├── .gitignore ├── vite.config.ts ├── src-wasm ├── Cargo.toml └── src │ └── lib.rs ├── .eslintrc.cjs ├── README.md ├── package.json ├── rsw.toml └── Cargo.lock /src/definitions/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /src-go/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/tcastelly/vute-taui-vite 2 | 3 | go 1.20 4 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "src-wasm", 4 | "src-tauri" 5 | ] 6 | 7 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcastelly/vue-tauri-vite/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcastelly/vue-tauri-vite/HEAD/src/assets/logo.png -------------------------------------------------------------------------------- /src/components/HelloTsx.tsx: -------------------------------------------------------------------------------- 1 | export default function () { 2 | return

With TSX

; 3 | } 4 | -------------------------------------------------------------------------------- /src-tauri/icons/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcastelly/vue-tauri-vite/HEAD/src-tauri/icons/icon.ico -------------------------------------------------------------------------------- /src-tauri/icons/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcastelly/vue-tauri-vite/HEAD/src-tauri/icons/icon.png -------------------------------------------------------------------------------- /src-tauri/icons/32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcastelly/vue-tauri-vite/HEAD/src-tauri/icons/32x32.png -------------------------------------------------------------------------------- /src-tauri/icons/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcastelly/vue-tauri-vite/HEAD/src-tauri/icons/icon.icns -------------------------------------------------------------------------------- /src-tauri/.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | WixTools 5 | -------------------------------------------------------------------------------- /src-tauri/icons/128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcastelly/vue-tauri-vite/HEAD/src-tauri/icons/128x128.png -------------------------------------------------------------------------------- /src-tauri/icons/StoreLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcastelly/vue-tauri-vite/HEAD/src-tauri/icons/StoreLogo.png -------------------------------------------------------------------------------- /src-tauri/icons/128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcastelly/vue-tauri-vite/HEAD/src-tauri/icons/128x128@2x.png -------------------------------------------------------------------------------- /src-tauri/icons/Square30x30Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcastelly/vue-tauri-vite/HEAD/src-tauri/icons/Square30x30Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square44x44Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcastelly/vue-tauri-vite/HEAD/src-tauri/icons/Square44x44Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square71x71Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcastelly/vue-tauri-vite/HEAD/src-tauri/icons/Square71x71Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square89x89Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcastelly/vue-tauri-vite/HEAD/src-tauri/icons/Square89x89Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square107x107Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcastelly/vue-tauri-vite/HEAD/src-tauri/icons/Square107x107Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square142x142Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcastelly/vue-tauri-vite/HEAD/src-tauri/icons/Square142x142Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square150x150Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcastelly/vue-tauri-vite/HEAD/src-tauri/icons/Square150x150Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square284x284Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcastelly/vue-tauri-vite/HEAD/src-tauri/icons/Square284x284Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square310x310Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcastelly/vue-tauri-vite/HEAD/src-tauri/icons/Square310x310Logo.png -------------------------------------------------------------------------------- /src/definitions/env.d.ts: -------------------------------------------------------------------------------- 1 | interface ImportMeta { 2 | env: { 3 | VITE_SOME_KEY: string, 4 | DEV: boolean, 5 | PROD: boolean, 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/definitions/src-wasm.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'src-wasm' { 2 | export * from '@/../src-wasm/pkg'; 3 | 4 | export default function (): Promise; 5 | } 6 | -------------------------------------------------------------------------------- /src/definitions/shims-vue.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import { ComponentOptions } from 'vue'; 3 | 4 | const component: ComponentOptions; 5 | export default component; 6 | } 7 | -------------------------------------------------------------------------------- /lint-staged.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | '*.{js,jsx,vue}': [ 3 | 'eslint --cache --ext .jsx,.js,.vue', 4 | ], 5 | '*.{ts,tsx}': [ 6 | () => 'tsc --skipLibCheck --noEmit', 7 | 'eslint --cache', 8 | ], 9 | }; 10 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue'; 2 | import rustWasmInit from 'src-wasm'; 3 | import App from './App.vue'; 4 | 5 | const main = async () => { 6 | await rustWasmInit(); 7 | 8 | createApp(App).mount('#app'); 9 | }; 10 | 11 | main(); 12 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src-tauri/rustfmt.toml: -------------------------------------------------------------------------------- 1 | max_width = 100 2 | hard_tabs = false 3 | tab_spaces = 2 4 | newline_style = "Auto" 5 | use_small_heuristics = "Default" 6 | reorder_imports = true 7 | reorder_modules = true 8 | remove_nested_parens = true 9 | edition = "2021" 10 | merge_derives = true 11 | use_try_shorthand = false 12 | use_field_init_shorthand = false 13 | force_explicit_abi = true 14 | imports_granularity = "Crate" 15 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | OSFLAG := 2 | UNAME_S := $(shell uname -s) 3 | ifeq ($(UNAME_S),Darwin) 4 | OSFLAG = osx 5 | endif 6 | 7 | OSFLAG := 8 | UNAME_S := $(shell uname -s) 9 | ifeq ($(UNAME_S),Darwin) 10 | OSFLAG = osx 11 | endif 12 | 13 | build: 14 | cd src-go && go get ./... && go build -buildmode=c-archive -o libgophernize.a main.go 15 | 16 | # force to re-build c lib 17 | buildc: 18 | go clean -cache && $(MAKE) build 19 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "target": "esnext", 5 | "module": "esnext", 6 | "moduleResolution": "node", 7 | "jsx": "preserve", 8 | "sourceMap": true, 9 | "resolveJsonModule": true, 10 | "esModuleInterop": true, 11 | "baseUrl": ".", 12 | "paths": { 13 | "@/*": [ 14 | "src/*" 15 | ] 16 | } 17 | }, 18 | "exclude": [ 19 | "dist", 20 | "node_modules", 21 | ], 22 | } 23 | -------------------------------------------------------------------------------- /.github/workflows/clean-workflow.yml: -------------------------------------------------------------------------------- 1 | name: "clean" 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | days_old: 6 | description: "The amount of days old to delete" 7 | default: "7" 8 | required: false 9 | 10 | jobs: 11 | clean-logs: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: igorjs/gh-actions-clean-workflow@v3 15 | with: 16 | token: ${{ secrets.GH_TOKEN }} 17 | days_old: ${{ github.event.inputs.days_old }} 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | target 5 | 6 | .eslintcache 7 | 8 | *.a 9 | *.h 10 | .rsw 11 | 12 | src-tauri/tauri.js 13 | .cargo/config.toml 14 | 15 | # local env files 16 | .env.local 17 | .env.*.local 18 | 19 | # Log files 20 | npm-debug.log* 21 | yarn-debug.log* 22 | yarn-error.log* 23 | pnpm-debug.log* 24 | 25 | src-wasm/pkg 26 | src-wasm/target 27 | 28 | # Editor directories and files 29 | .idea 30 | .vscode 31 | *.suo 32 | *.ntvs* 33 | *.njsproj 34 | *.sln 35 | *.sw? 36 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import { defineConfig } from 'vite'; 3 | import vueJsx from '@vitejs/plugin-vue-jsx'; 4 | import vue from '@vitejs/plugin-vue'; 5 | import { ViteRsw } from 'vite-plugin-rsw'; 6 | 7 | export default defineConfig({ 8 | plugins: [ 9 | vue(), 10 | vueJsx(), 11 | ViteRsw(), 12 | ], 13 | resolve: { 14 | alias: { 15 | '@': path.resolve(__dirname, '/src'), 16 | }, 17 | }, 18 | server: { 19 | port: 3222, 20 | hmr: { 21 | overlay: false, 22 | }, 23 | }, 24 | }); 25 | -------------------------------------------------------------------------------- /src-wasm/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "src-wasm" 3 | version = "0.1.4" 4 | authors = ["Thomas "] 5 | edition = "2021" 6 | 7 | # https://github.com/rustwasm/wasm-pack/issues/886 8 | # https://developers.google.com/web/updates/2019/02/hotpath-with-wasm 9 | [package.metadata.wasm-pack.profile.release] 10 | wasm-opt = false 11 | 12 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 13 | [lib] 14 | crate-type = ["cdylib", "rlib"] 15 | 16 | [profile.release] 17 | lto = true 18 | opt-level = "s" 19 | 20 | [dependencies] 21 | wasm-bindgen = "0.2" 22 | -------------------------------------------------------------------------------- /src-tauri/src/build.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2021 Tauri Programme within The Commons Conservancy 2 | // SPDX-License-Identifier: Apache-2.0 3 | // SPDX-License-Identifier: MIT 4 | 5 | use tauri_build::{try_build, Attributes, WindowsAttributes}; 6 | 7 | fn main() { 8 | let path = "./src-go"; 9 | let lib = "gophernize"; 10 | 11 | println!("cargo:rustc-link-search=native={}", path); 12 | println!("cargo:rustc-link-lib=static={}", lib); 13 | 14 | if let Err(error) = try_build( 15 | Attributes::new() 16 | .windows_attributes(WindowsAttributes::new().window_icon_path("../icons/icon.ico")), 17 | ) { 18 | panic!("error found during tauri-build: {}", error); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src-tauri/src/cmd.rs: -------------------------------------------------------------------------------- 1 | use serde::Deserialize; 2 | use tauri::command; 3 | 4 | use crate::MyState; 5 | 6 | #[derive(Debug, Deserialize)] 7 | pub struct RequestBody { 8 | id: i32, 9 | name: String, 10 | } 11 | 12 | #[command] 13 | pub fn log_operation(event: String, payload: Option) { 14 | println!("{} {:?}", event, payload); 15 | } 16 | 17 | #[command] 18 | pub fn perform_request(endpoint: String, body: RequestBody) -> String { 19 | println!("{} {:?}", endpoint, body); 20 | "message response".into() 21 | } 22 | 23 | #[command] 24 | pub async fn read_state(state: tauri::State<'_, MyState>) -> Result { 25 | println!("state: {:?}", state.0); 26 | 27 | Ok("done".to_string()) 28 | } 29 | -------------------------------------------------------------------------------- /src/components/Add.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | defineComponent, 3 | ref, 4 | watchEffect, 5 | } from 'vue'; 6 | import { add } from 'src-wasm'; 7 | 8 | export default defineComponent({ 9 | setup() { 10 | const nb1 = ref(0); 11 | const nb2 = ref(0); 12 | 13 | const res = ref(0); 14 | 15 | watchEffect(() => { 16 | res.value = add(+nb1.value, +nb2.value); 17 | }); 18 | 19 | return () => ( 20 | <> 21 |

With Wasm (Rust)

22 | 23 | 24 | + 25 | 26 | = 27 | {res.value} 28 | 29 | ); 30 | }, 31 | }); 32 | -------------------------------------------------------------------------------- /src-wasm/src/lib.rs: -------------------------------------------------------------------------------- 1 | use wasm_bindgen::prelude::*; 2 | 3 | // Import the `window.alert` function from the Web. 4 | #[wasm_bindgen] 5 | extern "C" { 6 | fn alert(s: &str); 7 | } 8 | 9 | // Export a `greet` function from Rust to JavaScript, that alerts a hello message. 10 | #[wasm_bindgen] 11 | pub fn greet(name: &str) { 12 | alert(&format!("Hi, {}!!!", name)); 13 | } 14 | 15 | #[wasm_bindgen] 16 | pub fn add(nb1: f32, nb2: f32) -> f32 { 17 | nb1 + nb2 18 | } 19 | 20 | // lifted from the `console_log` example 21 | #[wasm_bindgen] 22 | extern "C" { 23 | #[wasm_bindgen(js_namespace = console)] 24 | fn log(s: &str); 25 | } 26 | 27 | #[wasm_bindgen(start)] 28 | pub fn run() { 29 | log("Hello from Rust WASM!"); // should output "Hello from Rust WASM!" 30 | } 31 | -------------------------------------------------------------------------------- /src-tauri/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "app" 3 | version = "0.1.11" 4 | description = "A Tauri App" 5 | authors = ["thomas@castelly.fr"] 6 | license = "" 7 | repository = "" 8 | default-run = "app" 9 | edition = "2021" 10 | build = "src/build.rs" 11 | 12 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 13 | 14 | [build-dependencies] 15 | tauri-build = { version = "1", features = [] } 16 | 17 | [dependencies] 18 | serde_json = "1" 19 | serde = { version = "1", features = ["derive"] } 20 | tauri = { version = "1", features = ["api-all"] } 21 | 22 | [features] 23 | default = [ "custom-protocol" ] 24 | custom-protocol = [ "tauri/custom-protocol" ] 25 | 26 | # enable debug 27 | # [profile.release.package.wry] 28 | # debug = true 29 | # debug-assertions = true 30 | # ./node_modules/.bin/tauri build --debug 31 | # ./src-tauri/target/debug/bundle/appimage/vite-vue_0.1.1_amd64.AppImage 32 | -------------------------------------------------------------------------------- /src/definitions/shims-app.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.bmp' { 2 | const src: string; 3 | export default src; 4 | } 5 | 6 | declare module '*.gif' { 7 | const src: string; 8 | export default src; 9 | } 10 | 11 | declare module '*.jpg' { 12 | const src: string; 13 | export default src; 14 | } 15 | 16 | declare module '*.jpeg' { 17 | const src: string; 18 | export default src; 19 | } 20 | 21 | declare module '*.png' { 22 | const src: string; 23 | export default src; 24 | } 25 | 26 | declare module '*.webp' { 27 | const src: string; 28 | export default src; 29 | } 30 | 31 | declare module '*.module.css' { 32 | const classes: { readonly [key: string]: string }; 33 | export default classes; 34 | } 35 | 36 | declare module '*.module.scss' { 37 | const classes: { readonly [key: string]: string }; 38 | export default classes; 39 | } 40 | 41 | declare module '*.module.sass' { 42 | const classes: { readonly [key: string]: string }; 43 | export default classes; 44 | } 45 | -------------------------------------------------------------------------------- /src-go/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "C" 5 | "sort" 6 | "time" 7 | ) 8 | import "fmt" 9 | 10 | //export Concat 11 | func Concat(name string) *C.char { 12 | str := name + " ʕ ◔ϖ◔ʔ" 13 | 14 | return C.CString(str) 15 | } 16 | 17 | //export Timestamp 18 | func Timestamp() int64 { 19 | return time.Now().UnixNano() 20 | } 21 | 22 | //export Add 23 | func Add(nb1 int64, nb2 int64) int64 { 24 | return nb1 + nb2 25 | } 26 | 27 | //export Divide 28 | func Divide(nb1 float64, nb2 float64) float64 { 29 | return nb1 / nb2 30 | } 31 | 32 | //export Sort 33 | func Sort(vals []int32) []int32 { 34 | // len of slice is wrong 35 | sort.Slice(vals[:cap(vals)], func(i, j int) bool { 36 | return vals[i] < vals[j] 37 | }) 38 | 39 | return vals 40 | } 41 | 42 | //export MutateStr 43 | func MutateStr(str *string) { 44 | *str = "updated" 45 | } 46 | 47 | //export MutateInt 48 | func MutateInt(nb *int32) { 49 | *nb = 42 50 | } 51 | 52 | //export IsCorrect 53 | func IsCorrect() bool { 54 | return true 55 | } 56 | 57 | func main() { 58 | // try Mutate 59 | str := "hey" 60 | MutateStr(&str) 61 | fmt.Println(str) 62 | } 63 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | es6: true, 5 | }, 6 | extends: [ 7 | 'plugin:vue/vue3-essential', 8 | '@vue/eslint-config-airbnb-with-typescript', 9 | ], 10 | parserOptions: { 11 | ecmaVersion: 2020, 12 | parser: '@typescript-eslint/parser', 13 | }, 14 | parser: 'vue-eslint-parser', 15 | rules: { 16 | 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 17 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 18 | 'no-underscore-dangle': 'off', 19 | 'func-names': 0, 20 | 21 | // let ts manage modules 22 | 'import/no-extraneous-dependencies': 0, 23 | 24 | // will be resolved by TS 25 | 'import/no-unresolved': 0, 26 | 27 | // fix export/import default 28 | 'import/no-named-as-default': 0, 29 | 30 | '@typescript-eslint/ban-ts-comment': 'off', 31 | '@typescript-eslint/no-explicit-any': 0, 32 | '@typescript-eslint/explicit-module-boundary-types': 0, 33 | '@typescript-eslint/no-unused-vars': ['error'], 34 | 35 | // fix tsx component 36 | 'import/prefer-default-export': 0, 37 | }, 38 | }; 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tauri Application 2 | 3 | In this project I try to show how to use Tauri application with multiple technologies as: 4 | - VueJS with TypesScript 5 | - Wasm (Rust) 6 | - Vite for the client bundle 7 | - Go and Rust as backend thanks to ffi 8 | 9 | ## Launch dev 10 | 11 | - Install `rsw` 12 | > cargo install rsw 13 | - Install [wasm-pack](https://rustwasm.github.io/wasm-pack/installer/) 14 | 15 | ⚠️ Note: Open two terminal windows, execute `npm run watch` in the first and `npm run tauri:dev` in the second. **The order of execution is important, do not close the first window!** 16 | 17 | ## Update Dependencies 18 | 19 | - Javascript part: 20 | - package.json > "@tauri-apps/api" 21 | - Rust part: 22 | > cd src-tauri 23 | 24 | > cargo update -p tauri 25 | - and check 26 | - https://crates.io/crates/tauri/versions 27 | - https://crates.io/crates/tauri-build/versions 28 | 29 | ## Release build 30 | 31 | ### Github Actions 32 | Take a look to: 33 | https://github.com/tcastelly/vue-tauri-vite/blob/master/.github/workflows/release.yml 34 | 35 | ### Manual release 36 | Increase version of 37 | 38 | > package.json > version 39 | 40 | > src-tauri/Cargo.toml > version 41 | 42 | > src-tauri/tauri.conf.json > version 43 | 44 | > npm run tauri:build 45 | -------------------------------------------------------------------------------- /src/definitions/getContextValues.d.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | ExtractDefaultPropTypes, 3 | ExtractPropTypes, 4 | Ref, 5 | SetupContext, 6 | } from 'vue'; 7 | 8 | type Unwrap = T extends Ref ? U : T; 9 | 10 | type Slots = Partial<{ 11 | default: (...args: unknown[]) => unknown, 12 | [id: string]: (...args: unknown[]) => unknown, 13 | }>; 14 | 15 | type RemoveReadonly = { 16 | -readonly [P in keyof T]: T[P]; 17 | }; 18 | 19 | type EmitsAsObj = { 22 | [K in Extract]: (...args: Parameters) => any 23 | }; 24 | 25 | type EmitsAsArr> = RemoveReadonly; 26 | 27 | export type Emits | object)> = T extends ReadonlyArray 28 | ? EmitsAsArr 29 | : EmitsAsObj; 30 | 31 | export type Context any, Z extends { 32 | vSlots?: Slots 33 | } | unknown = Partial<{ vSlots?: Slots }>> = SetupContext & { 34 | [P in keyof ReturnType]: Unwrap[P]> 35 | } & { 36 | listeners: { [id: string]: (args?: any) => any }, 37 | $attrs: Record, 38 | $slots: Z extends { vSlots?: Slots } ? Z['vSlots'] : never, 39 | $emit: SetupContext['emit'], 40 | } & Omit; 41 | 42 | type PartiallyOptional = Omit & Partial>; 43 | 44 | export type ExternalProps> 45 | = PartiallyOptional, keyof ExtractDefaultPropTypes>; 46 | -------------------------------------------------------------------------------- /src-tauri/tauri.conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "package": { 3 | "productName": "tcy-demo", 4 | "version": "0.2.13" 5 | }, 6 | "build": { 7 | "distDir": "../dist", 8 | "devPath": "http://localhost:3222", 9 | "beforeDevCommand": "npm run start", 10 | "beforeBuildCommand": "npm run build" 11 | }, 12 | "tauri": { 13 | "bundle": { 14 | "active": true, 15 | "targets": "all", 16 | "identifier": "tcy.io", 17 | "icon": [ 18 | "icons/32x32.png", 19 | "icons/128x128.png", 20 | "icons/128x128@2x.png", 21 | "icons/icon.icns", 22 | "icons/icon.ico" 23 | ], 24 | "resources": [], 25 | "copyright": "", 26 | "category": "DeveloperTool", 27 | "shortDescription": "", 28 | "longDescription": "", 29 | "deb": { 30 | "depends": [] 31 | }, 32 | "macOS": { 33 | "frameworks": [], 34 | "minimumSystemVersion": "", 35 | "exceptionDomain": "", 36 | "signingIdentity": null, 37 | "entitlements": null 38 | }, 39 | "windows": { 40 | "certificateThumbprint": null, 41 | "digestAlgorithm": "sha256", 42 | "timestampUrl": "" 43 | } 44 | }, 45 | "updater": { 46 | "active": false 47 | }, 48 | "allowlist": { 49 | "all": true 50 | }, 51 | "windows": [ 52 | { 53 | "title": "TCY Demo", 54 | "width": 800, 55 | "height": 600, 56 | "resizable": true, 57 | "fullscreen": false 58 | } 59 | ], 60 | "security": { 61 | "csp": "script-src 'wasm-unsafe-eval' default-src blob: data: filesystem: ws: http: https: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self'" 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite-vue", 3 | "version": "0.0.18", 4 | "license": "MIT", 5 | "type": "module", 6 | "scripts": { 7 | "prebuild": "rsw build", 8 | "build": "vite build", 9 | "check-types": "tsc --noemit --skipLibCheck", 10 | "dev": "vite", 11 | "go:build": "make build", 12 | "lint": "npm run lint:eslint && npm run lint:tsc", 13 | "lint:eslint": "eslint --ext .jsx,.js,.ts,.tsx,.vue src/", 14 | "lint:fix": "eslint --ext .jsx,.js,.ts,.tsx,.vue src/ --fix", 15 | "lint:tsc": "eslint --quiet \"{tests,src}/**/*.{js,ts,tsx,vue}\" && npm run check-types", 16 | "rsw": "rsw", 17 | "start": "vite", 18 | "tauri": "tauri", 19 | "tauri:build": "npm run go:build && tauri build", 20 | "tauri:dev": "npm run go:build && tauri dev", 21 | "watch": "rsw watch" 22 | }, 23 | "dependencies": { 24 | "@tauri-apps/api": "^1.6.0", 25 | "@vitejs/plugin-vue": "^5.1.2", 26 | "@vitejs/plugin-vue-jsx": "^4.0.1", 27 | "fix": "^0.0.6", 28 | "vite": "^5.4.2", 29 | "vite-plugin-rsw": "^2.0.11", 30 | "vue": "^3.4.38" 31 | }, 32 | "devDependencies": { 33 | "@tauri-apps/cli": "^1.6.1", 34 | "@typescript-eslint/eslint-plugin": "^8.3.0", 35 | "@typescript-eslint/parser": "^8.3.0", 36 | "@vue/cli-plugin-eslint": "^5.0.8", 37 | "@vue/cli-plugin-typescript": "^5.0.8", 38 | "@vue/cli-service": "^5.0.8", 39 | "@vue/eslint-config-airbnb-with-typescript": "^8.0.0", 40 | "@vue/eslint-config-typescript": "^13.0.0", 41 | "eslint": "^8.45.0", 42 | "eslint-plugin-import": "^2.29.1", 43 | "eslint-plugin-vue": "^9.27.0", 44 | "lint-staged": "^15.2.9", 45 | "typescript": "^5.5.4", 46 | "wasm-pack": "^0.13.0" 47 | }, 48 | "gitHooks": { 49 | "pre-commit": "lint-staged" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: "publish" 2 | on: 3 | push: 4 | branches: 5 | - release 6 | 7 | jobs: 8 | publish-tauri: 9 | strategy: 10 | fail-fast: false 11 | matrix: 12 | platform: [macos-latest, ubuntu-latest] 13 | 14 | runs-on: ${{ matrix.platform }} 15 | steps: 16 | - uses: actions/checkout@v3 17 | - name: setup node 18 | uses: actions/setup-node@v3 19 | with: 20 | node-version: 20 21 | 22 | - name: Install Go 23 | uses: actions/setup-go@v3 24 | with: 25 | go-version: '1.23' 26 | 27 | - name: Checkout code 28 | uses: actions/checkout@v3 29 | 30 | - name: Build Go FFI 31 | run: make build 32 | 33 | - name: install Rust stable 34 | uses: actions-rs/toolchain@v1 35 | with: 36 | toolchain: stable 37 | 38 | - name: install webkit2gtk (ubuntu only) 39 | if: matrix.platform == 'ubuntu-latest' 40 | run: | 41 | sudo apt-get update 42 | sudo apt-get install -y webkit2gtk-4.0 43 | 44 | - name: install dependencies 45 | run: | 46 | curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh 47 | cargo install rsw 48 | npm ci --force 49 | 50 | - name: generate osx cargo config 51 | if: matrix.platform == 'macos-latest' 52 | run: make init_osx_cfg 53 | 54 | - name: tauri release 55 | uses: tauri-apps/tauri-action@v0 56 | env: 57 | GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} 58 | with: 59 | tagName: app-v__VERSION__ # the action automatically replaces \_\_VERSION\_\_ with the app version 60 | releaseName: "App v__VERSION__" 61 | body: "See the assets to download this version and install." 62 | draft: false 63 | prerelease: false 64 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 69 | 70 | 80 | -------------------------------------------------------------------------------- /src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 59 | 60 | 77 | 78 | 95 | -------------------------------------------------------------------------------- /rsw.toml: -------------------------------------------------------------------------------- 1 | name = "rsw" 2 | version = "0.1.0" 3 | 4 | #! time interval for file changes to trigger wasm-pack build, default `50` milliseconds 5 | interval = 50 6 | 7 | #! link 8 | #! npm link @see https://docs.npmjs.com/cli/v8/commands/npm-link 9 | #! yarn link @see https://classic.yarnpkg.com/en/docs/cli/link 10 | #! pnpm link @see https://pnpm.io/cli/link 11 | #! The link command will only be executed if `[[crates]] link = true` 12 | #! cli: `npm` | `yarn` | `pnpm`, default is `npm` 13 | cli = "npm" 14 | 15 | #! --------------------------- 16 | 17 | #! rsw new 18 | [new] 19 | #! @see https://rustwasm.github.io/docs/wasm-pack/commands/new.html 20 | #! using: `wasm-pack` | `rsw` | `user`, default is `wasm-pack` 21 | #! 1. wasm-pack: `rsw new --template