···44# paths because the flake.nix is written in a way such that top-level members
55# (`weaver-cli` and `weaver-server`) are built as different derivations which avoid being
66# rebuilt if the other package's sources change.
77-members = ["crates/*", "crates/weaver-server"]
77+members = ["crates/*", "crates/weaver-server", "crates/weaver-server"]
8899#default-members = ["crates/weaver-cli"]
1010···3939markdown-weaver = { git = "https://github.com/rsform/markdown-weaver" }
4040markdown-weaver-escape = { git = "https://github.com/rsform/markdown-weaver" }
41414242-jacquard = { git = "https://tangled.org/@nonbinary.computer/jacquard", default-features = false, features = ["derive", "api_bluesky", "dns"] }
4242+jacquard = { git = "https://tangled.org/@nonbinary.computer/jacquard", default-features = false, features = ["derive", "api_bluesky"] }
4343jacquard-api = { git = "https://tangled.org/@nonbinary.computer/jacquard" }
4444jacquard-axum = { git = "https://tangled.org/@nonbinary.computer/jacquard" }
4545-tree_magic = { version = "0.2.3", features = ["cli"] }
46454746[profile]
4847
···2525pub mod base_html;
2626pub mod code_pretty;
2727pub mod css;
2828+#[cfg(not(target_family = "wasm"))]
2829pub mod static_site;
2930pub mod theme;
3031pub mod types;
3132pub mod utils;
3333+#[cfg(not(target_family = "wasm"))]
3234pub mod walker;
33353436pub static OBSIDIAN_NOTE_LINK_RE: LazyLock<Regex> = LazyLock::new(|| {
···77# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8899[dependencies]
1010-dioxus = { version = "0.6.0", features = ["router", "fullstack"] }
1010+dashmap = "6.1.0"
1111+dioxus = { version = "0.7.0", features = ["router", "fullstack"] }
1112weaver-common = { path = "../weaver-common" }
1212-weaver-workspace-hack = { version = "0.1", path = "../weaver-workspace-hack" }
1313-1414-jacquard = { workspace = true, features = ["tracing"] }
1313+jacquard = { workspace = true, features = ["streaming"] }
1414+jacquard-axum = { workspace = true, optional = true }
1515+weaver-api = { path = "../weaver-api", features = ["streaming"] }
1616+markdown-weaver = { workspace = true }
1717+moka = { version = "0.12", features = ["future"], optional = true }
1818+mini-moka = { version = "0.10" }
1919+dioxus-primitives = { git = "https://github.com/DioxusLabs/components", version = "0.0.1", default-features = false }
15201621[features]
1722default = ["web"]
···2126desktop = ["dioxus/desktop"]
2227# The feature that are only required for the mobile = ["dioxus/mobile"] build target should be optional and only enabled in the mobile = ["dioxus/mobile"] feature
2328mobile = ["dioxus/mobile"]
2929+# The feature that are only required for the server = ["dioxus/server"] build target should be optional and only enabled in the server = ["dioxus/server"] feature
3030+server = ["dioxus/server", "dep:jacquard-axum", "dep:moka"]
···11-await-holding-invalid-types = [
22- "generational_box::GenerationalRef",
33- { path = "generational_box::GenerationalRef", reason = "Reads should not be held over an await point. This will cause any writes to fail while the await is pending since the read borrow is still active." },
44- "generational_box::GenerationalRefMut",
55- { path = "generational_box::GenerationalRefMut", reason = "Write should not be held over an await point. This will cause any reads or writes to fail while the await is pending since the write borrow is still active." },
66- "dioxus_signals::Write",
77- { path = "dioxus_signals::Write", reason = "Write should not be held over an await point. This will cause any reads or writes to fail while the await is pending since the write borrow is still active." },
88-]
···11-use dioxus::prelude::*;
22-33-const ECHO_CSS: Asset = asset!("/assets/styling/echo.css");
44-55-/// Echo component that demonstrates fullstack server functions.
66-#[component]
77-pub fn Echo() -> Element {
88- // use_signal is a hook. Hooks in dioxus must be run in a consistent order every time the component is rendered.
99- // That means they can't be run inside other hooks, async blocks, if statements, or loops.
1010- //
1111- // use_signal is a hook that creates a state for the component. It takes a closure that returns the initial value of the state.
1212- // The state is automatically tracked and will rerun any other hooks or components that read it whenever it changes.
1313- let mut response = use_signal(|| String::new());
1414-1515- rsx! {
1616- document::Link { rel: "stylesheet", href: ECHO_CSS }
1717-1818- div {
1919- id: "echo",
2020- h4 { "ServerFn Echo" }
2121- input {
2222- placeholder: "Type here to echo...",
2323- // `oninput` is an event handler that will run when the input changes. It can return either nothing or a future
2424- // that will be run when the event runs.
2525- oninput: move |event| async move {
2626- // When we call the echo_server function from the client, it will fire a request to the server and return
2727- // the response. It handles serialization and deserialization of the request and response for us.
2828- let data = echo_server(event.value()).await.unwrap();
2929-3030- // After we have the data from the server, we can set the state of the signal to the new value.
3131- // Since we read the `response` signal later in this component, the component will rerun.
3232- response.set(data);
3333- },
3434- }
3535-3636- // Signals can be called like a function to clone the current value of the signal
3737- if !response().is_empty() {
3838- p {
3939- "Server echoed: "
4040- // Since we read the signal inside this component, the component "subscribes" to the signal. Whenever
4141- // the signal changes, the component will rerun.
4242- i { "{response}" }
4343- }
4444- }
4545- }
4646- }
4747-}
4848-4949-// Server functions let us define public APIs on the server that can be called like a normal async function from the client.
5050-// Each server function needs to be annotated with the `#[server]` attribute, accept and return serializable types, and return
5151-// a `Result` with the error type [`ServerFnError`].
5252-//
5353-// When the server function is called from the client, it will just serialize the arguments, call the API, and deserialize the
5454-// response.
5555-#[server]
5656-async fn echo_server(input: String) -> Result<String, ServerFnError> {
5757- // The body of server function like this comment are only included on the server. If you have any server-only logic like
5858- // database queries, you can put it here. Any imports for the server function should either be imported inside the function
5959- // or imported under a `#[cfg(feature = "server")]` block.
6060- Ok(input)
6161-}
···11-use dioxus::prelude::*;
22-33-const HEADER_SVG: Asset = asset!("/assets/header.svg");
44-55-#[component]
66-pub fn Hero() -> Element {
77- rsx! {
88- // We can create elements inside the rsx macro with the element name followed by a block of attributes and children.
99- div {
1010- // Attributes should be defined in the element before any children
1111- id: "hero",
1212- // After all attributes are defined, we can define child elements and components
1313- img { src: HEADER_SVG, id: "header" }
1414- div { id: "links",
1515- // The RSX macro also supports text nodes surrounded by quotes
1616- a { href: "https://dioxuslabs.com/learn/0.6/", "📚 Learn Dioxus" }
1717- a { href: "https://dioxuslabs.com/awesome", "🚀 Awesome Dioxus" }
1818- a { href: "https://github.com/dioxus-community/", "📡 Community Libraries" }
1919- a { href: "https://github.com/DioxusLabs/sdk", "⚙️ Dioxus Development Kit" }
2020- a { href: "https://marketplace.visualstudio.com/items?itemName=DioxusLabs.dioxus", "💫 VSCode Extension" }
2121- a { href: "https://discord.gg/XgGxMSkvUM", "👋 Community Discord" }
2222- }
2323- }
2424- }
2525-}
+41
crates/weaver-server/src/components/identity.rs
···11+use crate::{fetch, Route};
22+use dioxus::prelude::*;
33+use jacquard::{
44+ client::BasicClient,
55+ types::{ident::AtIdentifier, tid::Tid},
66+ CowStr,
77+};
88+use weaver_api::sh_weaver::notebook::NotebookView;
99+#[component]
1010+pub fn Repository(ident: AtIdentifier<'static>) -> Element {
1111+ rsx! {
1212+ // We can create elements inside the rsx macro with the element name followed by a block of attributes and children.
1313+ div {
1414+ Outlet::<Route> {}
1515+ }
1616+ }
1717+}
1818+1919+#[component]
2020+pub fn RepositoryIndex(ident: AtIdentifier<'static>) -> Element {
2121+ let fetcher = use_context::<fetch::CachedFetcher>();
2222+ let notebooks = use_signal(|| fetcher.list_recent_notebooks());
2323+ rsx! {
2424+ for notebook in notebooks.iter() {
2525+ {
2626+ let view = ¬ebook.0;
2727+ rsx! {
2828+ div {
2929+ key: "{view.cid}",
3030+ NotebookCard { notebook: view.clone() }
3131+ }
3232+ }
3333+ }
3434+ }
3535+ }
3636+}
3737+3838+#[component]
3939+pub fn NotebookCard(notebook: NotebookView<'static>) -> Element {
4040+ rsx! {}
4141+}
+7-4
crates/weaver-server/src/components/mod.rs
···22//! They can be used to defined common UI elements like buttons, forms, and modals. In this template, we define a Hero
33//! component and an Echo component for fullstack apps to be used in our app.
4455-mod hero;
66-pub use hero::Hero;
55+mod cssblob;
66+77+mod entry;
88+pub use entry::{Entry, EntryCard};
7988-mod echo;
99-pub use echo::Echo;
1010+mod identity;
1111+pub use identity::{Repository, RepositoryIndex};
1212+pub mod avatar;
···11// The dioxus prelude contains a ton of common items used in dioxus apps. It's a good idea to import wherever you
22// need dioxus
33-use dioxus::prelude::*;
44-55-use views::{Blog, Home, Navbar};
33+use components::{Entry, Repository, RepositoryIndex};
44+use dioxus::{fullstack::FullstackContext, prelude::*};
55+use jacquard::{
66+ client::BasicClient, smol_str::SmolStr, types::did::Did, types::string::AtIdentifier, CowStr,
77+};
88+use std::sync::Arc;
99+use views::{Home, Navbar, Notebook, NotebookIndex, NotebookPage};
610711/// Define a components module that contains all shared components for our app.
812mod components;
1313+mod fetch;
914/// Define a views module that contains the UI for all Layouts and Routes for our app.
1015mod views;
11161217/// The Route enum is used to define the structure of internal routes in our app. All route enums need to derive
1318/// the [`Routable`] trait, which provides the necessary methods for the router to work.
1414-///
1919+///
1520/// Each variant represents a different URL pattern that can be matched by the router. If that pattern is matched,
1621/// the components for that route will be rendered.
1722#[derive(Debug, Clone, Routable, PartialEq)]
···2429 // the component for that route will be rendered. The component name that is rendered defaults to the variant name.
2530 #[route("/")]
2631 Home {},
2727- // The route attribute can include dynamic parameters that implement [`std::str::FromStr`] and [`std::fmt::Display`] with the `:` syntax.
2828- // In this case, id will match any integer like `/blog/123` or `/blog/-456`.
2929- #[route("/blog/:id")]
3030- // Fields of the route variant will be passed to the component as props. In this case, the blog component must accept
3131- // an `id` prop of type `i32`.
3232- Blog { id: i32 },
3232+ #[layout(ErrorLayout)]
3333+ #[nest("/:ident")]
3434+ #[layout(components::Repository)]
3535+ #[route("/")]
3636+ RepositoryIndex { ident: AtIdentifier<'static> },
3737+ #[nest("/:book_title")]
3838+ #[layout(views::Notebook)]
3939+ #[route("/")]
4040+ NotebookIndex { ident: AtIdentifier<'static>, book_title: SmolStr },
4141+ #[route("/:title")]
4242+ Entry { ident: AtIdentifier<'static>, book_title: SmolStr, title: SmolStr }
4343+3344}
34453546// We can import assets in dioxus with the `asset!` macro. This macro takes a path to an asset relative to the crate root.
···3950const MAIN_CSS: Asset = asset!("/assets/styling/main.css");
40514152fn main() {
4242- // The `launch` function is the main entry point for a dioxus app. It takes a component and renders it with the platform feature
4343- // you have enabled
5353+ // Run `serve()` on the server only
5454+ #[cfg(feature = "server")]
5555+ dioxus::serve(|| async move {
5656+ // Create a new router for our app using the `router` function
5757+ let mut router = dioxus::server::router(App);
5858+5959+ // .. customize the router, adding layers and new routes
6060+6161+ // And then return the router
6262+ Ok(router)
6363+ });
6464+6565+ // When not on the server, just run `launch()` like normal
6666+ #[cfg(not(feature = "server"))]
4467 dioxus::launch(App);
4568}
4669···5174#[component]
5275fn App() -> Element {
5376 // The `rsx!` macro lets us define HTML inside of rust. It expands to an Element with all of our HTML inside.
7777+ use_context_provider(|| fetch::CachedFetcher::new(Arc::new(BasicClient::unauthenticated())));
5478 rsx! {
5579 // In addition to element and text (which we will see later), rsx can contain other components. In this case,
5680 // we are using the `document::Link` component to add a link to our favicon and main CSS file into the head of our app.
···6387 Router::<Route> {}
6488 }
6589}
9090+9191+// And then our Outlet is wrapped in a fallback UI
9292+#[component]
9393+fn ErrorLayout() -> Element {
9494+ rsx! {
9595+ ErrorBoundary {
9696+ handle_error: move |err: ErrorContext| {
9797+ let http_error = FullstackContext::commit_error_status(err.error().unwrap());
9898+ match http_error.status {
9999+ StatusCode::NOT_FOUND => rsx! { div { "404 - Page not found" } },
100100+ _ => rsx! { div { "An unknown error occurred" } },
101101+ }
102102+ },
103103+ Outlet::<Route> {}
104104+ }
105105+ }
106106+}
107107+108108+struct Config {
109109+ did: Option<Did<'static>>,
110110+}
-39
crates/weaver-server/src/views/blog.rs
···11-use crate::Route;
22-use dioxus::prelude::*;
33-44-const BLOG_CSS: Asset = asset!("/assets/styling/blog.css");
55-66-/// The Blog page component that will be rendered when the current route is `[Route::Blog]`
77-///
88-/// The component takes a `id` prop of type `i32` from the route enum. Whenever the id changes, the component function will be
99-/// re-run and the rendered HTML will be updated.
1010-#[component]
1111-pub fn Blog(id: i32) -> Element {
1212- rsx! {
1313- document::Link { rel: "stylesheet", href: BLOG_CSS }
1414-1515- div {
1616- id: "blog",
1717-1818- // Content
1919- h1 { "This is blog #{id}!" }
2020- p { "In blog #{id}, we show how the Dioxus router works and how URL parameters can be passed as props to our route components." }
2121-2222- // Navigation links
2323- // The `Link` component lets us link to other routes inside our app. It takes a `to` prop of type `Route` and
2424- // any number of child nodes.
2525- Link {
2626- // The `to` prop is the route that the link should navigate to. We can use the `Route` enum to link to the
2727- // blog page with the id of -1. Since we are using an enum instead of a string, all of the routes will be checked
2828- // at compile time to make sure they are valid.
2929- to: Route::Blog { id: id - 1 },
3030- "Previous"
3131- }
3232- span { " <---> " }
3333- Link {
3434- to: Route::Blog { id: id + 1 },
3535- "Next"
3636- }
3737- }
3838- }
3939-}
+14-3
crates/weaver-server/src/views/home.rs
···11-use crate::components::{Echo, Hero};
11+use crate::{components::EntryCard, fetch};
22use dioxus::prelude::*;
3344/// The Home page component that will be rendered when the current route is `[Route::Home]`
55#[component]
66pub fn Home() -> Element {
77+ let fetcher = use_context::<fetch::CachedFetcher>();
88+ let entries = use_signal(|| fetcher.list_recent_entries());
79 rsx! {
88- Hero {}
99- Echo {}
1010+ for entry in entries.iter() {
1111+ {
1212+ let view = &entry.0;
1313+ rsx! {
1414+ div {
1515+ key: "{view.entry.cid}",
1616+ EntryCard { entry: view.clone() }
1717+ }
1818+ }
1919+ }
2020+ }
1021 }
1122}
+6-3
crates/weaver-server/src/views/mod.rs
···1111mod home;
1212pub use home::Home;
13131414-mod blog;
1515-pub use blog::Blog;
1616-1714mod navbar;
1815pub use navbar::Navbar;
1616+1717+mod notebookpage;
1818+pub use notebookpage::NotebookPage;
1919+2020+mod notebook;
2121+pub use notebook::{Notebook, NotebookIndex};
+1-4
crates/weaver-server/src/views/navbar.rs
···1919 to: Route::Home {},
2020 "Home"
2121 }
2222- Link {
2323- to: Route::Blog { id: 1 },
2424- "Blog"
2525- }
2222+2623 }
27242825 // The `Outlet` component is used to render the next component inside the layout. In this case, it will render either
+30
crates/weaver-server/src/views/notebook.rs
···11+use crate::{fetch, Route};
22+use dioxus::prelude::*;
33+use jacquard::{
44+ client::BasicClient,
55+ smol_str::SmolStr,
66+ types::{ident::AtIdentifier, tid::Tid},
77+ CowStr,
88+};
99+use std::sync::Arc;
1010+1111+const BLOG_CSS: Asset = asset!("/assets/styling/blog.css");
1212+1313+/// The Blog page component that will be rendered when the current route is `[Route::Blog]`
1414+///
1515+/// The component takes a `id` prop of type `i32` from the route enum. Whenever the id changes, the component function will be
1616+/// re-run and the rendered HTML will be updated.
1717+#[component]
1818+pub fn Notebook(ident: AtIdentifier<'static>, book_title: SmolStr) -> Element {
1919+ let fetcher = use_context::<fetch::CachedFetcher>();
2020+ rsx! {
2121+ document::Link { rel: "stylesheet", href: BLOG_CSS }
2222+ Outlet::<Route> {}
2323+ }
2424+}
2525+2626+#[component]
2727+pub fn NotebookIndex(ident: AtIdentifier<'static>, book_title: SmolStr) -> Element {
2828+ let fetcher = use_context::<fetch::CachedFetcher>();
2929+ rsx! {}
3030+}
+25
crates/weaver-server/src/views/notebookpage.rs
···11+use crate::Route;
22+use dioxus::prelude::*;
33+use jacquard::types::tid::Tid;
44+55+const BLOG_CSS: Asset = asset!("/assets/styling/blog.css");
66+77+/// The Blog page component that will be rendered when the current route is `[Route::Blog]`
88+///
99+/// The component takes a `id` prop of type `i32` from the route enum. Whenever the id changes, the component function will be
1010+/// re-run and the rendered HTML will be updated.
1111+#[component]
1212+pub fn NotebookPage(id: Tid, children: Element) -> Element {
1313+ rsx! {
1414+ document::Link { rel: "stylesheet", href: BLOG_CSS }
1515+1616+ div {
1717+ id: "blog",
1818+1919+ // Content
2020+ h1 { "This is blog #{id}!" }
2121+ p { "In blog #{id}, we show how the Dioxus router works and how URL parameters can be passed as props to our route components." }
2222+2323+ }
2424+ }
2525+}
-4
crates/weaver-workspace-hack/.gitattributes
···11-# Avoid putting conflict markers in the generated Cargo.toml file, since their presence breaks
22-# Cargo.
33-# Also do not check out the file as CRLF on Windows, as that's what hakari needs.
44-Cargo.toml merge=binary -crlf
-110
crates/weaver-workspace-hack/Cargo.toml
···11-# This file is generated by `cargo hakari`.
22-# To regenerate, run:
33-# cargo hakari generate
44-55-[package]
66-name = "weaver-workspace-hack"
77-version = "0.1.0"
88-description = "workspace-hack package, managed by hakari"
99-license.workspace = true
1010-edition.workspace = true
1111-# You can choose to publish this crate: see https://docs.rs/cargo-hakari/latest/cargo_hakari/publishing.
1212-publish = false
1313-1414-# The parts of the file between the BEGIN HAKARI SECTION and END HAKARI SECTION comments
1515-# are managed by hakari.
1616-1717-### BEGIN HAKARI SECTION
1818-[dependencies]
1919-aho-corasick = { version = "1" }
2020-byteorder = { version = "1" }
2121-bytes = { version = "1", features = ["serde"] }
2222-data-encoding = { version = "2" }
2323-diesel = { version = "2", features = ["chrono", "i-implement-a-third-party-backend-and-opt-into-breaking-changes", "postgres", "serde_json", "sqlite"] }
2424-diesel-async = { version = "0.5", features = ["deadpool", "postgres", "sync-connection-wrapper"] }
2525-elliptic-curve = { version = "0.13", features = ["digest", "hazmat", "jwk", "pem", "std"] }
2626-futures-channel = { version = "0.3", features = ["sink"] }
2727-futures-core = { version = "0.3" }
2828-futures-task = { version = "0.3", default-features = false, features = ["std"] }
2929-futures-util = { version = "0.3", features = ["channel", "io", "sink"] }
3030-generic-array = { version = "0.14", default-features = false, features = ["more_lengths", "serde", "zeroize"] }
3131-hashbrown = { version = "0.15", features = ["serde"] }
3232-idna = { version = "1" }
3333-jacquard = { git = "https://tangled.org/@nonbinary.computer/jacquard", default-features = false, features = ["api_bluesky", "derive", "dns", "loopback", "tracing", "websocket", "zstd"] }
3434-jacquard-api = { git = "https://tangled.org/@nonbinary.computer/jacquard", features = ["bluesky", "sh_weaver"] }
3535-jacquard-common = { git = "https://tangled.org/@nonbinary.computer/jacquard", features = ["tracing", "websocket", "zstd"] }
3636-jacquard-identity = { git = "https://tangled.org/@nonbinary.computer/jacquard", default-features = false, features = ["cache", "dns", "tracing"] }
3737-jacquard-lexicon = { git = "https://tangled.org/@nonbinary.computer/jacquard" }
3838-jacquard-oauth = { git = "https://tangled.org/@nonbinary.computer/jacquard", features = ["browser-open", "loopback", "tracing"] }
3939-log = { version = "0.4", default-features = false, features = ["std"] }
4040-memchr = { version = "2" }
4141-miette = { version = "7", features = ["fancy", "syntect-highlighter"] }
4242-minijinja = { version = "2" }
4343-minimal-lexical = { version = "0.2", default-features = false, features = ["std"] }
4444-nom = { version = "7" }
4545-num-traits = { version = "0.2", default-features = false, features = ["i128", "libm", "std"] }
4646-p384 = { version = "0.13", default-features = false, features = ["ecdsa"] }
4747-percent-encoding = { version = "2" }
4848-rand = { version = "0.8", features = ["small_rng"] }
4949-regex-automata = { version = "0.4", default-features = false, features = ["dfa", "hybrid", "meta", "nfa", "perf", "std", "unicode"] }
5050-reqwest = { version = "0.12", features = ["gzip", "json", "rustls-tls", "stream"] }
5151-sec1 = { version = "0.7", features = ["pem", "serde", "std", "subtle"] }
5252-serde_json = { version = "1", features = ["alloc", "preserve_order", "raw_value"] }
5353-sha2 = { version = "0.10", features = ["oid"] }
5454-smallvec = { version = "1", default-features = false, features = ["const_new"] }
5555-subtle = { version = "2" }
5656-syn = { version = "2", features = ["extra-traits", "fold", "full", "visit", "visit-mut"] }
5757-syntect = { version = "5", features = ["default-fancy"] }
5858-time = { version = "0.3", features = ["formatting", "macros", "parsing"] }
5959-tokio = { version = "1", features = ["full"] }
6060-tokio-util = { version = "0.7", features = ["codec", "io"] }
6161-toml = { version = "0.8", features = ["preserve_order"] }
6262-tower-http = { version = "0.6", features = ["cors", "fs", "normalize-path", "request-id", "timeout", "trace"] }
6363-tracing = { version = "0.1", features = ["log"] }
6464-tracing-core = { version = "0.1" }
6565-uuid = { version = "1", features = ["serde", "v4", "v7"] }
6666-winnow = { version = "0.7" }
6767-zerocopy = { version = "0.8", default-features = false, features = ["derive", "simd"] }
6868-zeroize = { version = "1", features = ["derive", "serde"] }
6969-7070-[build-dependencies]
7171-aho-corasick = { version = "1" }
7272-bytes = { version = "1", features = ["serde"] }
7373-data-encoding = { version = "2" }
7474-diesel_derives = { version = "2", features = ["32-column-tables", "chrono", "postgres", "sqlite", "with-deprecated"] }
7575-elliptic-curve = { version = "0.13", features = ["digest", "hazmat", "jwk", "pem", "std"] }
7676-futures-channel = { version = "0.3", features = ["sink"] }
7777-futures-core = { version = "0.3" }
7878-futures-task = { version = "0.3", default-features = false, features = ["std"] }
7979-futures-util = { version = "0.3", features = ["channel", "io", "sink"] }
8080-generic-array = { version = "0.14", default-features = false, features = ["more_lengths", "serde", "zeroize"] }
8181-idna = { version = "1" }
8282-jacquard-common = { git = "https://tangled.org/@nonbinary.computer/jacquard", features = ["tracing", "websocket", "zstd"] }
8383-jacquard-lexicon = { git = "https://tangled.org/@nonbinary.computer/jacquard" }
8484-log = { version = "0.4", default-features = false, features = ["std"] }
8585-memchr = { version = "2" }
8686-miette = { version = "7", features = ["fancy", "syntect-highlighter"] }
8787-minimal-lexical = { version = "0.2", default-features = false, features = ["std"] }
8888-nom = { version = "7" }
8989-num-traits = { version = "0.2", default-features = false, features = ["i128", "libm", "std"] }
9090-percent-encoding = { version = "2" }
9191-rand = { version = "0.8", features = ["small_rng"] }
9292-regex-automata = { version = "0.4", default-features = false, features = ["dfa", "hybrid", "meta", "nfa", "perf", "std", "unicode"] }
9393-reqwest = { version = "0.12", features = ["gzip", "json", "rustls-tls", "stream"] }
9494-sec1 = { version = "0.7", features = ["pem", "serde", "std", "subtle"] }
9595-serde_json = { version = "1", features = ["alloc", "preserve_order", "raw_value"] }
9696-sha2 = { version = "0.10", features = ["oid"] }
9797-smallvec = { version = "1", default-features = false, features = ["const_new"] }
9898-subtle = { version = "2" }
9999-syn = { version = "2", features = ["extra-traits", "fold", "full", "visit", "visit-mut"] }
100100-syntect = { version = "5", features = ["default-fancy"] }
101101-time = { version = "0.3", features = ["formatting", "macros", "parsing"] }
102102-tokio = { version = "1", features = ["full"] }
103103-tokio-util = { version = "0.7", features = ["codec", "io"] }
104104-tracing = { version = "0.1", features = ["log"] }
105105-tracing-core = { version = "0.1" }
106106-winnow = { version = "0.7" }
107107-zerocopy = { version = "0.8", default-features = false, features = ["derive", "simd"] }
108108-zeroize = { version = "1", features = ["derive", "serde"] }
109109-110110-### END HAKARI SECTION
-2
crates/weaver-workspace-hack/build.rs
···11-// A build script is required for cargo to consider build dependencies.
22-fn main() {}