Set up wasm generation (#42)
This commit is contained in:
parent
2d89355566
commit
2161f594bf
35
.github/workflows/deploy.yml
vendored
Normal file
35
.github/workflows/deploy.yml
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
name: Deploy
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
CARGO_TERM_COLOR: always
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
web:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: web
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: '22'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Build SvelteKit project
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
- name: Deploy Project Artifacts to Vercel
|
||||||
|
run: npx vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
|
||||||
|
env:
|
||||||
|
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
|
||||||
|
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
|
||||||
35
.github/workflows/preview.yml
vendored
Normal file
35
.github/workflows/preview.yml
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
name: Deploy
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches-ignore:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
CARGO_TERM_COLOR: always
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
web:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: web
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: '22'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Build SvelteKit project
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
- name: Deploy Project Artifacts to Vercel
|
||||||
|
run: npx vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }}
|
||||||
|
env:
|
||||||
|
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
|
||||||
|
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
|
||||||
@ -1,8 +1,10 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## Next
|
## Next
|
||||||
- Switch to the fastnum crate's d128
|
- Create a [website interface](https://cpc.kasper.space)
|
||||||
- Fix exp function
|
- Add wasm version
|
||||||
|
- Switch to the `fastnum` crate's d128
|
||||||
|
- Fix `exp` function
|
||||||
|
|
||||||
## 2.0.0 - 2025 May 30
|
## 2.0.0 - 2025 May 30
|
||||||
- Remove the `degrees` keyword which referred to `celcius` by default
|
- Remove the `degrees` keyword which referred to `celcius` by default
|
||||||
|
|||||||
157
Cargo.lock
generated
157
Cargo.lock
generated
@ -23,13 +23,39 @@ version = "0.12.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f781dba93de3a5ef6dc5b17c9958b208f6f3f021623b360fb605ea51ce443f10"
|
checksum = "f781dba93de3a5ef6dc5b17c9958b208f6f3f021623b360fb605ea51ce443f10"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "3.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "console_error_panic_hook"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cpc"
|
name = "cpc"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"console_error_panic_hook",
|
||||||
"fastnum",
|
"fastnum",
|
||||||
|
"js-sys",
|
||||||
"regex",
|
"regex",
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"web-time",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -42,12 +68,52 @@ dependencies = [
|
|||||||
"bnum",
|
"bnum",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.77"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.7.4"
|
version = "2.7.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.21.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.95"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.40"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.11.1"
|
version = "1.11.1"
|
||||||
@ -77,8 +143,99 @@ version = "0.8.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.101"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-segmentation"
|
name = "unicode-segmentation"
|
||||||
version = "1.12.0"
|
version = "1.12.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
"rustversion",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-backend"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"log",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-backend",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "web-time"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
|
||||||
|
dependencies = [
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|||||||
@ -18,9 +18,18 @@ categories = [
|
|||||||
"value-formatting",
|
"value-formatting",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib", "rlib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
fastnum = "0.2"
|
fastnum = "0.2"
|
||||||
unicode-segmentation = "1.12"
|
unicode-segmentation = "1.12"
|
||||||
|
web-time = "1.1.0"
|
||||||
|
|
||||||
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
|
console_error_panic_hook = "0.1.7"
|
||||||
|
wasm-bindgen = "0.2"
|
||||||
|
js-sys = "0.3"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
regex = "1.11"
|
regex = "1.11"
|
||||||
|
|||||||
@ -11,6 +11,10 @@ It also lets you mix units, so for example `1 km - 1m` results in `999 Meter`.
|
|||||||
|
|
||||||
[List of all supported units](https://docs.rs/cpc/latest/cpc/units/enum.Unit.html)
|
[List of all supported units](https://docs.rs/cpc/latest/cpc/units/enum.Unit.html)
|
||||||
|
|
||||||
|
## ## [Web Interface](https://cpc.kasper.space)
|
||||||
|
|
||||||
|
Try it out at [cpc.kasper.space](https://cpc.kasper.space)
|
||||||
|
|
||||||
## CLI Installation
|
## CLI Installation
|
||||||
Install using `cargo`:
|
Install using `cargo`:
|
||||||
```
|
```
|
||||||
|
|||||||
17
src/lib.rs
17
src/lib.rs
@ -25,7 +25,7 @@
|
|||||||
use crate::units::Unit;
|
use crate::units::Unit;
|
||||||
use fastnum::{dec128 as d, D128};
|
use fastnum::{dec128 as d, D128};
|
||||||
use std::fmt::{self, Display};
|
use std::fmt::{self, Display};
|
||||||
use std::time::Instant;
|
use web_time::Instant;
|
||||||
|
|
||||||
/// Turns an [`AstNode`](parser::AstNode) into a [`Number`]
|
/// Turns an [`AstNode`](parser::AstNode) into a [`Number`]
|
||||||
pub mod evaluator;
|
pub mod evaluator;
|
||||||
@ -284,6 +284,21 @@ pub fn eval(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn wasm_eval(expression: &str) -> String {
|
||||||
|
console_error_panic_hook::set_once();
|
||||||
|
|
||||||
|
let result = eval(expression, true, false);
|
||||||
|
match result {
|
||||||
|
Ok(result) => result.to_string(),
|
||||||
|
Err(e) => format!("Error: {e}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
23
web/.gitignore
vendored
Normal file
23
web/.gitignore
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
node_modules
|
||||||
|
|
||||||
|
# Output
|
||||||
|
.output
|
||||||
|
.vercel
|
||||||
|
.netlify
|
||||||
|
.wrangler
|
||||||
|
/.svelte-kit
|
||||||
|
/build
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Env
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
!.env.test
|
||||||
|
|
||||||
|
# Vite
|
||||||
|
vite.config.js.timestamp-*
|
||||||
|
vite.config.ts.timestamp-*
|
||||||
38
web/README.md
Normal file
38
web/README.md
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# sv
|
||||||
|
|
||||||
|
Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli).
|
||||||
|
|
||||||
|
## Creating a project
|
||||||
|
|
||||||
|
If you're seeing this, you've probably already done this step. Congrats!
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# create a new project in the current directory
|
||||||
|
npx sv create
|
||||||
|
|
||||||
|
# create a new project in my-app
|
||||||
|
npx sv create my-app
|
||||||
|
```
|
||||||
|
|
||||||
|
## Developing
|
||||||
|
|
||||||
|
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
|
||||||
|
# or start the server and open the app in a new browser tab
|
||||||
|
npm run dev -- --open
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
To create a production version of your app:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
You can preview the production build with `npm run preview`.
|
||||||
|
|
||||||
|
> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
|
||||||
5970
web/package-lock.json
generated
Normal file
5970
web/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
31
web/package.json
Normal file
31
web/package.json
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"name": "web",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.1",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"build-wasm": "npx wasm-pack build --target bundler",
|
||||||
|
"dev": "npm run build-wasm && vite dev",
|
||||||
|
"build": "npm run build-wasm && vite build",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"prepare": "svelte-kit sync || echo ''",
|
||||||
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||||
|
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@sveltejs/adapter-vercel": "^5.7.2",
|
||||||
|
"@sveltejs/kit": "^2.16.0",
|
||||||
|
"@sveltejs/vite-plugin-svelte": "^5.0.0",
|
||||||
|
"@tailwindcss/vite": "^4.0.0",
|
||||||
|
"cpc": "file:../pkg",
|
||||||
|
"svelte": "^5.0.0",
|
||||||
|
"svelte-check": "^4.0.0",
|
||||||
|
"tailwindcss": "^4.0.0",
|
||||||
|
"typescript": "^5.0.0",
|
||||||
|
"vercel": "^42.2.0",
|
||||||
|
"vite": "^6.2.6",
|
||||||
|
"vite-plugin-top-level-await": "^1.5.0",
|
||||||
|
"vite-plugin-wasm": "^3.4.1",
|
||||||
|
"wasm-pack": "^0.13.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
web/src/app.css
Normal file
1
web/src/app.css
Normal file
@ -0,0 +1 @@
|
|||||||
|
@import 'tailwindcss';
|
||||||
13
web/src/app.d.ts
vendored
Normal file
13
web/src/app.d.ts
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// See https://svelte.dev/docs/kit/types#app.d.ts
|
||||||
|
// for information about these interfaces
|
||||||
|
declare global {
|
||||||
|
namespace App {
|
||||||
|
// interface Error {}
|
||||||
|
// interface Locals {}
|
||||||
|
// interface PageData {}
|
||||||
|
// interface PageState {}
|
||||||
|
// interface Platform {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {};
|
||||||
19
web/src/app.html
Normal file
19
web/src/app.html
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
|
||||||
|
<link rel="icon" type="image/png" href="%sveltekit.assets%/favicon-96x96.png" sizes="96x96" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="%sveltekit.assets%/favicon.svg" />
|
||||||
|
<link rel="shortcut icon" href="%sveltekit.assets%/favicon.ico" />
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="%sveltekit.assets%/apple-touch-icon.png" />
|
||||||
|
<meta name="apple-mobile-web-app-title" content="cpc" />
|
||||||
|
<link rel="manifest" href="%sveltekit.assets%/site.webmanifest" />
|
||||||
|
|
||||||
|
%sveltekit.head%
|
||||||
|
</head>
|
||||||
|
<body data-sveltekit-preload-data="hover">
|
||||||
|
<div style="display: contents">%sveltekit.body%</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
39
web/src/lib/helpers.ts
Normal file
39
web/src/lib/helpers.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
type ShortcutOptions = {
|
||||||
|
shift?: boolean
|
||||||
|
alt?: boolean
|
||||||
|
cmd_or_ctrl?: boolean
|
||||||
|
}
|
||||||
|
const is_mac = navigator.userAgent.indexOf('Mac') !== -1
|
||||||
|
|
||||||
|
function check_modifiers(e: KeyboardEvent | MouseEvent, options: ShortcutOptions) {
|
||||||
|
const target = {
|
||||||
|
shift: options.shift || false,
|
||||||
|
alt: options.alt || false,
|
||||||
|
ctrl: (!is_mac && options.cmd_or_ctrl) || false,
|
||||||
|
meta: (is_mac && options.cmd_or_ctrl) || false,
|
||||||
|
}
|
||||||
|
|
||||||
|
const pressed = {
|
||||||
|
shift: !!e.shiftKey,
|
||||||
|
alt: !!e.altKey,
|
||||||
|
ctrl: !!e.ctrlKey,
|
||||||
|
meta: !!e.metaKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
const ignore_ctrl = is_mac && e instanceof MouseEvent
|
||||||
|
|
||||||
|
return (
|
||||||
|
pressed.shift === target.shift &&
|
||||||
|
pressed.alt === target.alt &&
|
||||||
|
(pressed.ctrl === target.ctrl || ignore_ctrl) &&
|
||||||
|
pressed.meta === target.meta
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function check_shortcut(e: KeyboardEvent, key: string, options: ShortcutOptions = {}) {
|
||||||
|
if (e.key.toUpperCase() !== key.toUpperCase()) return false
|
||||||
|
return check_modifiers(e, options)
|
||||||
|
}
|
||||||
|
export function check_mouse_shortcut(e: MouseEvent, options: ShortcutOptions = {}) {
|
||||||
|
return check_modifiers(e, options)
|
||||||
|
}
|
||||||
7
web/src/routes/+layout.svelte
Normal file
7
web/src/routes/+layout.svelte
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import "../app.css";
|
||||||
|
|
||||||
|
let { children } = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{@render children()}
|
||||||
2
web/src/routes/+layout.ts
Normal file
2
web/src/routes/+layout.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export const ssr = false;
|
||||||
|
export const prerender = true;
|
||||||
99
web/src/routes/+page.svelte
Normal file
99
web/src/routes/+page.svelte
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { check_shortcut } from "$lib/helpers";
|
||||||
|
import { wasm_eval } from "cpc";
|
||||||
|
import { flip } from "svelte/animate";
|
||||||
|
import { fly } from "svelte/transition";
|
||||||
|
|
||||||
|
let input = $state("");
|
||||||
|
let output = $derived.by(() => {
|
||||||
|
try {
|
||||||
|
if (input.trim().length === 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return wasm_eval(input);
|
||||||
|
} catch (e) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let saved_queries: { id: number; in: string; out: string }[] = $state([]);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<main class="w-full px-4 lg:px-8 text-base lg:text-lg">
|
||||||
|
<nav class="flex items-center justify-between py-4 lg:py-6">
|
||||||
|
<h1 class="text-3xl font-bold text-amber-600 dark:text-amber-400">
|
||||||
|
cpc
|
||||||
|
</h1>
|
||||||
|
<a
|
||||||
|
href="https://github.com/probablykasper/cpc"
|
||||||
|
aria-label="GitHub repository"
|
||||||
|
class="svelte-1ugh5mt"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
height="24"
|
||||||
|
viewBox="-2 -2 28 28"
|
||||||
|
width="24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class="svelte-8lfi33 svelte-1ugh5mt"
|
||||||
|
><path
|
||||||
|
d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
class="svelte-8lfi33"
|
||||||
|
></path></svg
|
||||||
|
>
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="border border-gray-500/50 w-full rounded-lg px-3 py-2 outline-none"
|
||||||
|
bind:value={input}
|
||||||
|
onkeydown={(e) => {
|
||||||
|
if (check_shortcut(e, "Enter")) {
|
||||||
|
const input = e.currentTarget.value;
|
||||||
|
let out;
|
||||||
|
try {
|
||||||
|
out = wasm_eval(e.currentTarget.value);
|
||||||
|
} catch (e) {
|
||||||
|
out = "";
|
||||||
|
}
|
||||||
|
console.log(out);
|
||||||
|
saved_queries.unshift({
|
||||||
|
id: saved_queries.length,
|
||||||
|
in: input,
|
||||||
|
out,
|
||||||
|
});
|
||||||
|
e.currentTarget.value = "";
|
||||||
|
output = "";
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
placeholder="10km/h * 1 decade in light seconds"
|
||||||
|
/>
|
||||||
|
<div class="pt-1 leading-tight">
|
||||||
|
<div class="px-3 py-2">
|
||||||
|
{output}<span class="invisible select-none">x</span>
|
||||||
|
</div>
|
||||||
|
{#each saved_queries as query (query.id)}
|
||||||
|
<div
|
||||||
|
class="px-3 py-2"
|
||||||
|
in:fly={{ y: -10, duration: 150 }}
|
||||||
|
animate:flip={{ duration: 150 }}
|
||||||
|
>
|
||||||
|
<p class="opacity-65 text-base leading-tight">{query.in}</p>
|
||||||
|
<p>{query.out}</p>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<style lang="postcss">
|
||||||
|
@reference "../app.css";
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:global(body) {
|
||||||
|
@apply bg-black text-white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
BIN
web/static/apple-touch-icon.png
Normal file
BIN
web/static/apple-touch-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
BIN
web/static/favicon-96x96.png
Normal file
BIN
web/static/favicon-96x96.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
BIN
web/static/favicon.ico
Normal file
BIN
web/static/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
3
web/static/favicon.svg
Normal file
3
web/static/favicon.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 16 KiB |
21
web/static/site.webmanifest
Normal file
21
web/static/site.webmanifest
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"name": "cpc",
|
||||||
|
"short_name": "cpc",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "/web-app-manifest-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "maskable"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/web-app-manifest-512x512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "maskable"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"theme_color": "#faff00",
|
||||||
|
"background_color": "#000000",
|
||||||
|
"display": "standalone"
|
||||||
|
}
|
||||||
BIN
web/static/web-app-manifest-192x192.png
Normal file
BIN
web/static/web-app-manifest-192x192.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
BIN
web/static/web-app-manifest-512x512.png
Normal file
BIN
web/static/web-app-manifest-512x512.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
9
web/svelte.config.js
Normal file
9
web/svelte.config.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import adapter from '@sveltejs/adapter-vercel';
|
||||||
|
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
preprocess: vitePreprocess(),
|
||||||
|
kit: { adapter: adapter() }
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
19
web/tsconfig.json
Normal file
19
web/tsconfig.json
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"extends": "./.svelte-kit/tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"allowJs": true,
|
||||||
|
"checkJs": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"strict": true,
|
||||||
|
"moduleResolution": "bundler"
|
||||||
|
}
|
||||||
|
// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
|
||||||
|
// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
|
||||||
|
//
|
||||||
|
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
|
||||||
|
// from the referenced tsconfig.json - TypeScript does not merge them in
|
||||||
|
}
|
||||||
14
web/vite.config.ts
Normal file
14
web/vite.config.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import tailwindcss from '@tailwindcss/vite';
|
||||||
|
import { sveltekit } from '@sveltejs/kit/vite';
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import wasm from 'vite-plugin-wasm';
|
||||||
|
import top_level_await from 'vite-plugin-top-level-await';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [tailwindcss(), sveltekit(), wasm(), top_level_await()],
|
||||||
|
server: {
|
||||||
|
fs: {
|
||||||
|
allow: ['../pkg']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user