diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index af71975..47ea100 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -9,20 +9,12 @@ jobs: - uses: actions/checkout@v3 - uses: dtolnay/rust-toolchain@master with: - toolchain: nightly-2024-03-03 # duplicated in rust-toolchain.toml targets: wasm32-unknown-unknown components: clippy, rustfmt - uses: Swatinem/rust-cache@v2 - with: - # Additional non workspace directories to be cached, separated by newlines. - cache-directories: "" - name: rustfmt run: cargo fmt --check - name: clippy - # empty directories for rust-embed - run: | - mkdir app/dist - mkdir docs/book - cargo clippy -- -D warnings + run: cargo clippy -- -D warnings - name: tests run: cargo test diff --git a/.gitignore b/.gitignore index 2d40e88..ecaa062 100644 --- a/.gitignore +++ b/.gitignore @@ -2,11 +2,8 @@ target **/*.rs.bk -# leptos -app/dist - -# mdbook -docs/book +# cargo-run-bin +.bin # Mac OS shenanigans .DS_Store diff --git a/Cargo.lock b/Cargo.lock index bfd6e29..4c0d090 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -212,7 +212,7 @@ dependencies = [ "serde_urlencoded", "sync_wrapper 1.0.1", "tokio", - "tower", + "tower 0.4.13", "tower-layer", "tower-service", "tracing", @@ -256,7 +256,7 @@ dependencies = [ "mime", "pin-project-lite", "serde", - "tower", + "tower 0.4.13", "tower-layer", "tower-service", "tracing", @@ -379,12 +379,12 @@ dependencies = [ "mime_guess", "oauth2", "reqwest", - "rust-embed", "serde", "serde_json", "sha2", "tempfile", "tokio", + "tower 0.5.1", "tower-http", "tracing", "tracing-subscriber", @@ -1069,7 +1069,7 @@ dependencies = [ "pin-project-lite", "socket2", "tokio", - "tower", + "tower 0.4.13", "tower-service", "tracing", ] @@ -1909,41 +1909,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "rust-embed" -version = "8.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19549741604902eb99a7ed0ee177a0663ee1eda51a29f71401f166e47e77806a" -dependencies = [ - "axum", - "rust-embed-impl", - "rust-embed-utils", - "walkdir", -] - -[[package]] -name = "rust-embed-impl" -version = "8.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb9f96e283ec64401f30d3df8ee2aaeb2561f34c824381efa24a35f79bf40ee4" -dependencies = [ - "proc-macro2", - "quote", - "rust-embed-utils", - "syn", - "walkdir", -] - -[[package]] -name = "rust-embed-utils" -version = "8.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38c74a686185620830701348de757fd36bef4aa9680fd23c49fc539ddcc1af32" -dependencies = [ - "sha2", - "walkdir", -] - [[package]] name = "rustc-demangle" version = "0.1.24" @@ -2520,11 +2485,21 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +dependencies = [ + "tower-layer", + "tower-service", +] + [[package]] name = "tower-http" -version = "0.5.2" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" +checksum = "403fa3b783d4b626a8ad51d766ab03cb6d2dbfc46b1c5d4448395e6628dc9697" dependencies = [ "async-compression", "bitflags", @@ -2549,15 +2524,15 @@ dependencies = [ [[package]] name = "tower-layer" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" diff --git a/Cargo.toml b/Cargo.toml index 245eb48..a68f452 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,3 +14,9 @@ repository = "https://github.com/senekor/buenzlimarks" models = { path = "./models", package = "buenzlimarks_models" } serde = { version = "1.0", features = ["derive"] } serde_json = "1" + +[workspace.metadata.bin] +cargo-watch = { version = "8.5.3" } +mdbook = { version = "0.4.40" } +trunk = { version = "0.21.4" } +watchexec-cli = { version = "2.2.0", bins = ["watchexec"] } diff --git a/Containerfile b/Containerfile new file mode 100644 index 0000000..a863fbb --- /dev/null +++ b/Containerfile @@ -0,0 +1,55 @@ +from rust:bookworm as build-base + +run mkdir /work +workdir /work + +# install build tools tools +run curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash +run cargo binstall -y cargo-run-bin +copy Cargo.toml Cargo.lock . +run cargo bin --install +run rustup target add wasm32-unknown-unknown + +from build-base as build-docs + +copy docs docs +workdir /work/docs +run cargo bin mdbook build + +from build-base as build-deps + +copy models models +copy server/Cargo.toml server/ + +workdir /work/app +copy app/Cargo.toml app/Trunk.toml app/index.html app/tailwind.config.js app/tailwind.css . +copy app/assets assets +run mkdir src && echo "fn main() {}" > src/main.rs +run cargo bin trunk build --release + +workdir /work/server +run mkdir src && echo "fn main() {}" > src/main.rs && touch src/lib.rs +run cargo build --release --bin buenzlimarks + +from build-deps as build-app + +workdir /work/app +copy app/src src +run touch src/main.rs && cargo bin trunk build --release + +from build-deps as build-server + +workdir /work/server +copy server/src src +run touch src/main.rs src/lib.rs && cargo build --release --bin buenzlimarks + +from debian:bookworm-slim + +# expected by tokio::signal::ctrl_c +stopsignal SIGINT + +copy --from=build-docs /work/target/docs /docs +copy --from=build-app /work/target/app /app +copy --from=build-server /work/target/release/buenzlimarks /usr/local/bin/ + +cmd [ "/usr/local/bin/buenzlimarks" ] diff --git a/app/Cargo.toml b/app/Cargo.toml index d719309..6257226 100644 --- a/app/Cargo.toml +++ b/app/Cargo.toml @@ -12,8 +12,8 @@ gloo = { version = "0.11.0", default-features = false, features = [ "net", "storage", ] } -leptos = { version = "0.6.0", features = ["csr", "nightly"] } -leptos_router = { version = "0.6.0", features = ["csr", "nightly"] } +leptos = { version = "0.6.0", features = ["csr"] } +leptos_router = { version = "0.6.0", features = ["csr"] } models = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } diff --git a/app/Trunk.toml b/app/Trunk.toml index c697c53..173f0c6 100644 --- a/app/Trunk.toml +++ b/app/Trunk.toml @@ -1,3 +1,8 @@ +[build] +dist = "../target/app" + [serve] port = 3000 -proxy_backend = "http://localhost:4000/api" + +[[proxy]] +backend = "http://localhost:4000/api" diff --git a/app/src/auth/context.rs b/app/src/auth/context.rs index d5838c7..c00abd2 100644 --- a/app/src/auth/context.rs +++ b/app/src/auth/context.rs @@ -59,7 +59,7 @@ impl Auth { let navigate = use_navigate(); batch(|| { - (self.set_token)(Token(Some(new_token))); + self.set_token.set(Token(Some(new_token))); navigate("/", Default::default()); }); }); @@ -71,7 +71,7 @@ impl Auth { let navigate = use_navigate(); batch(|| { - (self.set_token)(Token(None)); + self.set_token.set(Token(None)); navigate("/", Default::default()); }); } diff --git a/app/src/auth/guard.rs b/app/src/auth/guard.rs index 9319c21..0e0743f 100644 --- a/app/src/auth/guard.rs +++ b/app/src/auth/guard.rs @@ -6,7 +6,7 @@ use crate::auth::use_token; pub fn create_auth_guard() { let token = use_token(); create_effect(move |_| { - if token().into_inner().is_none() { + if token.get().into_inner().is_none() { let navigate = use_navigate(); // workaround for navigating during initial routing // https://docs.rs/leptos_router/0.4.2/leptos_router/fn.use_navigate.html#panics diff --git a/app/src/auth/login.rs b/app/src/auth/login.rs index f6fb51e..1d55bbe 100644 --- a/app/src/auth/login.rs +++ b/app/src/auth/login.rs @@ -16,7 +16,7 @@ fn DevelLogin() -> impl IntoView { class="bg-slate-600 p-2 rounded text-white text-center text-3xl" placeholder="Enter a user name" prop:value=user_id - on:input=move |ev| set_user_id(event_target_value(&ev)) + on:input=move |ev| set_user_id.set(event_target_value(&ev)) on:keydown=move |ev| { if &ev.key() == "Enter" { submit() diff --git a/app/src/components/add_button.rs b/app/src/components/add_button.rs index 6252dd7..231003c 100644 --- a/app/src/components/add_button.rs +++ b/app/src/components/add_button.rs @@ -28,16 +28,16 @@ pub fn AddButton() -> impl IntoView { let (state, set_state) = create_signal::(State::None); create_effect(move |prev| { - if !edit_mode() && prev.is_some() { - set_state(State::None); + if !edit_mode.get() && prev.is_some() { + set_state.set(State::None); } }); - let on_close = move || set_state(State::None); + let on_close = move || set_state.set(State::None); view! {
@@ -50,27 +50,27 @@ pub fn AddButton() -> impl IntoView {
- - - + + +
- + - + - + - + diff --git a/app/src/components/bookmark.rs b/app/src/components/bookmark.rs index 4643a29..2804a15 100644 --- a/app/src/components/bookmark.rs +++ b/app/src/components/bookmark.rs @@ -16,39 +16,39 @@ pub fn Bookmark(bookmark: BookmarkType) -> impl IntoView { let bookmark = store_value(bookmark); let edit_mode = use_edit_mode().read(); - let no_edit_mode = Signal::derive(move || !edit_mode()); + let no_edit_mode = Signal::derive(move || !edit_mode.get()); let (form_open, set_form_open) = create_signal(false); - let on_close = move || set_form_open(false); + let on_close = move || set_form_open.set(false); view! { - + - + diff --git a/app/src/components/bookmark_form.rs b/app/src/components/bookmark_form.rs index b64ca2f..2feae37 100644 --- a/app/src/components/bookmark_form.rs +++ b/app/src/components/bookmark_form.rs @@ -16,22 +16,24 @@ pub fn BookmarkForm( let (page_id, set_page_id) = create_signal::>>(None); let pages = store.pages(); - if let Some(bookmark) = prev_bookmark() { + if let Some(bookmark) = prev_bookmark.get_value() { let all_widgets = store.widgets(); create_effect(move |_| { - let p_id = all_widgets() + let p_id = all_widgets + .get() .into_iter() .find(|w| w.id == bookmark.widget_id) .map(|w| w.page_id); - set_page_id(p_id); + set_page_id.set(p_id); }); }; let (widget_id, set_widget_id) = - create_signal::>>(prev_bookmark().map(|b| b.widget_id)); + create_signal::>>(prev_bookmark.get_value().map(|b| b.widget_id)); let page_widgets = create_memo(move |_| { - page_id() - .map(|id| store.widgets_by(id)()) + page_id + .get() + .map(|id| store.widgets_by(id).get()) .unwrap_or_default() }); @@ -48,37 +50,44 @@ pub fn BookmarkForm( } }); - let (name, set_name) = - create_signal::(prev_bookmark().map(|b| b.name).unwrap_or_default()); + let (name, set_name) = create_signal::( + prev_bookmark + .get_value() + .map(|b| b.name) + .unwrap_or_default(), + ); let (url, set_url) = - create_signal::(prev_bookmark().map(|b| b.url).unwrap_or_default()); + create_signal::(prev_bookmark.get_value().map(|b| b.url).unwrap_or_default()); let bookmark = Signal::derive(move || Bookmark { - id: prev_bookmark().map(|b| b.id).unwrap_or_else(|| "".into()), - name: name(), - url: url(), - widget_id: widget_id().unwrap_or_else(|| "".into()), + id: prev_bookmark + .get_value() + .map(|b| b.id) + .unwrap_or_else(|| "".into()), + name: name.get(), + url: url.get(), + widget_id: widget_id.get().unwrap_or_else(|| "".into()), }); view! { @@ -123,13 +132,13 @@ pub fn BookmarkForm( class="bg-slate-600 rounded px-2 py-1.5" placeholder="Name" prop:value=name - on:input=move |ev| set_name(event_target_value(&ev)) + on:input=move |ev| set_name.set(event_target_value(&ev)) />
- + - + - + diff --git a/app/src/components/widget.rs b/app/src/components/widget.rs index 11305e8..c9968c1 100644 --- a/app/src/components/widget.rs +++ b/app/src/components/widget.rs @@ -19,48 +19,48 @@ pub fn Widget(widget: WidgetType) -> impl IntoView { let edit_mode = use_edit_mode().read(); let (form_open, set_form_open) = create_signal(false); - let on_form_close = move || set_form_open(false); + let on_form_close = move || set_form_open.set(false); let (delete_open, set_delete_open) = create_signal(false); - let on_delete_close = move || set_delete_open(false); + let on_delete_close = move || set_delete_open.set(false); view! {
-

{ widget().name }

+

{ widget.get_value().name }

- -
- + - + - + diff --git a/app/src/components/widget_form.rs b/app/src/components/widget_form.rs index eac6089..f7b2f00 100644 --- a/app/src/components/widget_form.rs +++ b/app/src/components/widget_form.rs @@ -14,7 +14,7 @@ pub fn WidgetForm( let prev_widget = store_value(prev_widget); let (page_id, set_page_id) = - create_signal::>>(prev_widget().map(|w| w.page_id)); + create_signal::>>(prev_widget.get_value().map(|w| w.page_id)); let pages = store.pages(); // Force DOM update when pages are fetched such that page name is @@ -29,31 +29,34 @@ pub fn WidgetForm( }); let (name, set_name) = - create_signal::(prev_widget().map(|b| b.name).unwrap_or_default()); + create_signal::(prev_widget.get_value().map(|b| b.name).unwrap_or_default()); let widget = Signal::derive(move || Widget { - id: prev_widget().map(|b| b.id).unwrap_or_else(|| "".into()), - name: name(), - page_id: page_id().unwrap_or_else(|| "".into()), + id: prev_widget + .get_value() + .map(|b| b.id) + .unwrap_or_else(|| "".into()), + name: name.get(), + page_id: page_id.get().unwrap_or_else(|| "".into()), }); view! {