diff --git a/.github/workflows/web.yml b/.github/workflows/web.yml index 1ee20b0..579c541 100644 --- a/.github/workflows/web.yml +++ b/.github/workflows/web.yml @@ -17,10 +17,20 @@ jobs: cache: 'npm' cache-dependency-path: viewer/package-lock.json + - name: Install wasm-pack + uses: jetli/wasm-pack-action@v0.4.0 + + - name: Cache WASM build + uses: actions/cache@v3 + with: + path: target + key: doesnt-matter-share-everything + - name: Build web app run: | cd viewer npm ci + npm run wasm npm run build --if-present - name: Publish diff --git a/Cargo.lock b/Cargo.lock index 3332776..1d95e62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -140,6 +140,12 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +[[package]] +name = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + [[package]] name = "byteorder" version = "1.4.3" @@ -515,6 +521,15 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -558,6 +573,11 @@ checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "lts" version = "0.1.0" +dependencies = [ + "serde", + "serde-wasm-bindgen", + "wasm-bindgen", +] [[package]] name = "memchr" @@ -855,6 +875,17 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-wasm-bindgen" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + [[package]] name = "serde_derive" version = "1.0.188" @@ -966,6 +997,60 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + [[package]] name = "which" version = "4.4.0" diff --git a/lts/Cargo.toml b/lts/Cargo.toml index 352cd01..ca9ad18 100644 --- a/lts/Cargo.toml +++ b/lts/Cargo.toml @@ -3,4 +3,10 @@ name = "lts" version = "0.1.0" edition = "2021" -[dependencies] +[lib] +crate-type = ["cdylib", "rlib"] + +[target.'cfg(target_arch = "wasm32")'.dependencies] +serde = { version = "1.0.188", features = ["derive"] } +serde-wasm-bindgen = "0.5.0" +wasm-bindgen = "0.2.87" diff --git a/lts/src/lib.rs b/lts/src/lib.rs index 34df0c3..af37404 100644 --- a/lts/src/lib.rs +++ b/lts/src/lib.rs @@ -2,6 +2,8 @@ mod bike_ottawa; mod parse; mod speed_limit_only; mod tags; +#[cfg(target_arch = "wasm32")] +mod wasm; pub use bike_ottawa::bike_ottawa; pub use speed_limit_only::speed_limit_only; diff --git a/lts/src/wasm.rs b/lts/src/wasm.rs new file mode 100644 index 0000000..827e2b8 --- /dev/null +++ b/lts/src/wasm.rs @@ -0,0 +1,43 @@ +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use wasm_bindgen::prelude::*; + +use crate::{bike_ottawa, speed_limit_only, Tags, LTS}; + +#[derive(Deserialize)] +struct Input { + // TODO Improve this API + method: String, + tags: HashMap, +} + +#[derive(Serialize)] +struct Output { + lts: usize, + messages: Vec, +} + +#[wasm_bindgen()] +pub fn calculate(input: JsValue) -> Result { + let input: Input = serde_wasm_bindgen::from_value(input)?; + let mut tags = Tags::new(); + for (k, v) in input.tags { + tags.insert(k, v); + } + + let (lts, messages) = if input.method == "speed_limit_only" { + speed_limit_only::speed_limit_only(tags) + } else if input.method == "bike_ottawa" { + bike_ottawa::bike_ottawa(tags) + } else { + ( + LTS::NotAllowed, + vec![format!("Unknown method {}", input.method)], + ) + }; + let result = serde_wasm_bindgen::to_value(&Output { + lts: lts.into_json(), + messages, + })?; + Ok(result) +} diff --git a/viewer/package-lock.json b/viewer/package-lock.json index dd80458..7d014da 100644 --- a/viewer/package-lock.json +++ b/viewer/package-lock.json @@ -23,7 +23,8 @@ "svelte-check": "^3.4.4", "tslib": "^2.6.0", "typescript": "^5.1.3", - "vite": "^4.3.9" + "vite": "^4.3.9", + "vite-plugin-wasm-pack": "0.1.11" } }, "node_modules/@ampproject/remapping": { @@ -1470,6 +1471,20 @@ "node": ">=8" } }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1778,6 +1793,18 @@ "node": ">=6" } }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/just-compare": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/just-compare/-/just-compare-2.3.0.tgz", @@ -1980,6 +2007,12 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/narrowing": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/narrowing/-/narrowing-1.5.0.tgz", + "integrity": "sha512-DUu4XdKgkfAPTAL28k79pdnshDE2W5T24QAnidSPo2F/W1TX6CjNzmEeXQfE5O1lxQvC0GYI6ZRDsLcyzugEYA==", + "dev": true + }, "node_modules/node-releases": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", @@ -2676,6 +2709,15 @@ "node": ">=0.10.0" } }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/update-browserslist-db": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", @@ -2761,6 +2803,87 @@ } } }, + "node_modules/vite-plugin-wasm-pack": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/vite-plugin-wasm-pack/-/vite-plugin-wasm-pack-0.1.11.tgz", + "integrity": "sha512-eImq3bVNUXd2MAjz9WztqLSKabvWf6/7x2KDJdPYYqQncDOo7IqvuSvQiGW+8ihRgbI3uQuzqAL5AG4vAoHcEg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2", + "fs-extra": "^10.0.0", + "narrowing": "^1.4.0" + } + }, + "node_modules/vite-plugin-wasm-pack/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/vite-plugin-wasm-pack/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/vite-plugin-wasm-pack/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/vite-plugin-wasm-pack/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/vite-plugin-wasm-pack/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/vite-plugin-wasm-pack/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/vitefu": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.4.tgz", diff --git a/viewer/package.json b/viewer/package.json index ce3019e..7dd9593 100644 --- a/viewer/package.json +++ b/viewer/package.json @@ -6,6 +6,7 @@ "scripts": { "dev": "vite", "build": "vite build", + "wasm": "wasm-pack build --release --target web ../lts", "preview": "vite preview", "check": "svelte-check --tsconfig ./tsconfig.json", "fmt": "npx prettier --write *.html src/**" @@ -21,7 +22,8 @@ "svelte-check": "^3.4.4", "tslib": "^2.6.0", "typescript": "^5.1.3", - "vite": "^4.3.9" + "vite": "^4.3.9", + "vite-plugin-wasm-pack": "0.1.11" }, "dependencies": { "@turf/bbox": "^6.5.0", diff --git a/viewer/src/App.svelte b/viewer/src/App.svelte index a29620d..48f9441 100644 --- a/viewer/src/App.svelte +++ b/viewer/src/App.svelte @@ -1,10 +1,12 @@ Count: {properties.count.toFixed(2)} +LTS (Rust): {ltsResult.lts}
    - {#each result.message as msg} + {#each ltsResult.messages as msg}
  • {msg}
  • {/each}
diff --git a/viewer/vite.config.ts b/viewer/vite.config.ts index 60aa04b..bbeffb4 100644 --- a/viewer/vite.config.ts +++ b/viewer/vite.config.ts @@ -1,6 +1,7 @@ import { defineConfig } from "vite"; import { resolve } from "path"; import { svelte } from "@sveltejs/vite-plugin-svelte"; +import wasmPack from "vite-plugin-wasm-pack"; export default defineConfig({ base: "/routing-engines/", @@ -11,11 +12,5 @@ export default defineConfig({ }, }, }, - plugins: [svelte()], - // TODO For the symlinks in assets - server: { - fs: { - allow: [".."], - }, - }, + plugins: [svelte(), wasmPack(["../lts"], [])] })