Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
d225422
emit
pikaju Aug 23, 2026
7cfb13b
stream impl
pikaju Aug 23, 2026
54e85aa
yield_all
pikaju Aug 23, 2026
5117180
impl view response
pikaju Aug 23, 2026
2750701
wip
pikaju Aug 23, 2026
b650145
page fix
pikaju Aug 23, 2026
38c70bd
progress
pikaju Aug 23, 2026
8916925
fix layout
pikaju Aug 23, 2026
9c079e8
wip
pikaju Aug 23, 2026
11c8ace
optimize page with layouts
pikaju Aug 23, 2026
e19d7be
fix git merge thingies
pikaju Aug 23, 2026
bdf0dcc
view trait
pikaju Aug 24, 2026
591d6f5
node view parts stream
pikaju Aug 24, 2026
63bd260
node view parts stream impls
pikaju Aug 24, 2026
70d83b3
view chunk enum
pikaju Aug 24, 2026
c3bce98
join
pikaju Aug 24, 2026
a33823b
wip
pikaju Aug 24, 2026
314f1be
wip
pikaju Aug 24, 2026
fc74761
wip
pikaju Aug 24, 2026
4d3704d
wip
pikaju Aug 24, 2026
06c7cc4
first working prototype
pikaju Aug 24, 2026
e8b7614
Merge branch 'main' into view-stream
pikaju Aug 24, 2026
d240b93
fix unused async warning
pikaju Aug 24, 2026
aab060f
wip
pikaju Aug 25, 2026
8fcad45
ditch viewstream
pikaju Aug 25, 2026
05d5ecd
thenview and emitview
pikaju Aug 25, 2026
ffe37e4
progress
pikaju Aug 25, 2026
5f342fa
cx view
pikaju Aug 25, 2026
7690c75
progress
pikaju Aug 25, 2026
20701ee
move view
pikaju Aug 25, 2026
491f93d
wip
pikaju Aug 25, 2026
2119a15
refactor
pikaju Aug 25, 2026
d22ed10
fmt
pikaju Aug 25, 2026
68fdfb2
refactor buffer export structure
pikaju Aug 25, 2026
2b64e3f
revamp attribtues
pikaju Aug 25, 2026
c09033f
optimize attributes macro
pikaju Aug 25, 2026
0716b90
update tests
pikaju Aug 25, 2026
9b46c8b
async into response
pikaju Aug 25, 2026
ef62446
wip
pikaju Aug 25, 2026
4c27971
async into response 2
pikaju Aug 25, 2026
87a08a7
add view handle response impl
pikaju Aug 26, 2026
09bf8ba
wip
pikaju Aug 26, 2026
8413c33
mechanical changes
pikaju Aug 26, 2026
c650935
improve expr
pikaju Aug 26, 2026
b05e0a6
fix layout
pikaju Aug 26, 2026
7cc8863
remove needless box
pikaju Aug 26, 2026
21e87bc
remove vec based attribute value collector
pikaju Aug 26, 2026
e47a028
remove more dead code
pikaju Aug 26, 2026
8532817
add .single method to view ext
pikaju Aug 26, 2026
3c71347
fix lifetime issue
pikaju Aug 26, 2026
23aaa11
pass view buffer as component parameter
pikaju Aug 27, 2026
615bf82
update view trait
pikaju Aug 27, 2026
85399c2
wip
pikaju Aug 27, 2026
56a8e25
fix examples
pikaju Aug 27, 2026
f6522df
fix error handling example
pikaju Aug 27, 2026
0c97221
fix alpine ajax example
pikaju Aug 27, 2026
808adf2
bring back slot imports
pikaju Aug 27, 2026
8f1b3a7
simplify layout macro
pikaju Aug 27, 2026
c510451
rename marker to component
pikaju Aug 27, 2026
d042515
lifetimes
pikaju Aug 27, 2026
94ae584
refactor page grammar
pikaju Aug 27, 2026
caf94ab
remove lazy children for now
pikaju Aug 27, 2026
8c3b7ca
fix page
pikaju Aug 27, 2026
3419f2c
remove arc mutex from view buffer
pikaju Aug 27, 2026
7b8db53
wip
pikaju Aug 27, 2026
d6ec3b7
optimize loop view codegen
pikaju Aug 27, 2026
556024e
switch to node classify trait
pikaju Aug 27, 2026
a9b0c7d
add inlines
pikaju Aug 27, 2026
af78468
test new codegen
pikaju Aug 27, 2026
1283694
Revert "test new codegen"
pikaju Aug 27, 2026
c2085b2
human rewrite part 1
pikaju Aug 29, 2026
2da2577
human rewrite part 2
pikaju Aug 31, 2026
92b2b30
human rewrite part 3
pikaju Aug 31, 2026
8b3923d
implement live view
pikaju Aug 31, 2026
b0f6b2c
wip
pikaju Aug 31, 2026
49a3236
wip
pikaju Aug 31, 2026
738ee85
fix issues
pikaju Aug 31, 2026
cbcec7f
use thenview instead of moveview for layout and page
pikaju Aug 31, 2026
52a054a
optimize emit codegen
pikaju Aug 31, 2026
52c524c
fix performance regression
pikaju Aug 31, 2026
2219e01
fix
pikaju Aug 31, 2026
fc7d978
fix tests
pikaju Aug 31, 2026
a02f7dc
wip
pikaju Aug 31, 2026
97a2b77
simplify boxed components
pikaju Aug 31, 2026
e08935c
improve loop fairness
pikaju Aug 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 22 additions & 36 deletions benchmarks/axum-maud/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 9 additions & 9 deletions benchmarks/topcoat/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use topcoat::{
Result,
asset::{Asset, AssetBundle, RouterBuilderAssetExt, asset},
context::{Cx, app_context},
router::{Compression, Router, layout, page},
view::view,
router::{Compression, Router, Slot, layout, page},
view::{View, view},
};

use crate::{
Expand All @@ -27,8 +27,8 @@ pub fn router() -> Router {
}

#[layout]
async fn root_layout(slot: Result) -> Result {
view! {
async fn root_layout(slot: Slot<'_>) -> Result<impl View> {
Ok(view! {
<!DOCTYPE html>
<html lang="en">
<head>
Expand All @@ -39,16 +39,16 @@ async fn root_layout(slot: Result) -> Result {
</head>
<body class="flex min-h-screen flex-col bg-slate-50 text-slate-900">
site_nav()
<main class="mx-auto w-full max-w-6xl flex-1 px-4 py-8">(slot?)</main>
<main class="mx-auto w-full max-w-6xl flex-1 px-4 py-8">(slot)</main>
site_footer()
</body>
</html>
}
})
}

#[page]
async fn home(cx: &Cx) -> Result {
view! {
async fn home(cx: &Cx) -> Result<impl View> {
Ok(view! {
<section class="rounded-2xl bg-indigo-600 px-8 py-16 text-white">
<h1 class="max-w-2xl text-4xl font-bold tracking-tight">
"Gear that earns its place on your desk"
Expand Down Expand Up @@ -79,5 +79,5 @@ async fn home(cx: &Cx) -> Result {
}
</div>
</section>
}
})
}
50 changes: 25 additions & 25 deletions benchmarks/topcoat/src/app/_components.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use topcoat::{
Result,
view::{PromotedStr, StaticClass, class, component, view},
view::{PromotedStr, StaticClass, View, class, component, view},
};

use crate::{
Expand Down Expand Up @@ -59,8 +59,8 @@ const FOOTER_COLUMNS: [(&str, [(&str, &str); 4]); 4] = [
];

#[component]
pub async fn site_nav() -> Result {
view! {
pub async fn site_nav() -> Result<impl View> {
Ok(view! {
<header class="border-b border-slate-200 bg-white">
<nav
class="mx-auto flex w-full max-w-6xl items-center justify-between px-4 py-4"
Expand All @@ -79,12 +79,12 @@ pub async fn site_nav() -> Result {
</div>
</nav>
</header>
}
})
}

#[component]
pub async fn site_footer() -> Result {
view! {
pub async fn site_footer() -> Result<impl View> {
Ok(view! {
<footer class="border-t border-slate-200 bg-white">
<div
class="mx-auto grid w-full max-w-6xl grid-cols-2 gap-8 px-4 py-10 text-sm md:grid-cols-4"
Expand All @@ -108,14 +108,14 @@ pub async fn site_footer() -> Result {
</p>
</div>
</footer>
}
})
}

#[component]
pub async fn rating_stars(tenths: u32, size: &str) -> Result {
pub async fn rating_stars(tenths: u32, size: &str) -> Result<impl View> {
let filled = filled_stars(tenths);

view! {
Ok(view! {
<div class="flex">
for index in 0..5u32 {
<svg
Expand All @@ -131,12 +131,12 @@ pub async fn rating_stars(tenths: u32, size: &str) -> Result {
</svg>
}
</div>
}
})
}

#[component]
pub async fn product_card(product: &Product) -> Result {
view! {
pub async fn product_card(product: &Product) -> Result<impl View> {
Ok(view! {
<a
href=(("/products/", product.id))
class="group flex flex-col rounded-xl border border-slate-200 bg-white p-4 shadow-sm transition hover:shadow-md"
Expand Down Expand Up @@ -165,7 +165,7 @@ pub async fn product_card(product: &Product) -> Result {
</div>
<p class="mt-3 text-lg font-bold">(product.price())</p>
</a>
}
})
}

#[component]
Expand All @@ -174,8 +174,8 @@ pub async fn pagination(
page_count: usize,
sort: Option<&str>,
category: Option<&str>,
) -> Result {
view! {
) -> Result<impl View> {
Ok(view! {
<nav
aria-label="Pagination"
class="mt-10 flex flex-wrap items-center justify-center gap-1 text-sm"
Expand Down Expand Up @@ -204,12 +204,12 @@ pub async fn pagination(
<span class=(PAGE_DISABLED)>"Next"</span>
}
</nav>
}
})
}

#[component]
pub async fn breadcrumbs(category: &str, category_slug: &str, name: &str) -> Result {
view! {
pub async fn breadcrumbs(category: &str, category_slug: &str, name: &str) -> Result<impl View> {
Ok(view! {
<nav aria-label="Breadcrumb" class="text-sm text-slate-500">
<ol class="flex flex-wrap items-center gap-2">
<li><a href="/" class="hover:text-slate-900">"Home"</a></li>
Expand All @@ -228,12 +228,12 @@ pub async fn breadcrumbs(category: &str, category_slug: &str, name: &str) -> Res
<li class="font-medium text-slate-900">(name)</li>
</ol>
</nav>
}
})
}

#[component]
pub async fn spec_table(specs: &[Spec]) -> Result {
view! {
pub async fn spec_table(specs: &[Spec]) -> Result<impl View> {
Ok(view! {
<div class="mt-6 overflow-hidden rounded-xl border border-slate-200 bg-white">
<table class="w-full text-sm">
<tbody>
Expand All @@ -251,12 +251,12 @@ pub async fn spec_table(specs: &[Spec]) -> Result {
</tbody>
</table>
</div>
}
})
}

#[component]
pub async fn review_list(reviews: &[Review]) -> Result {
view! {
pub async fn review_list(reviews: &[Review]) -> Result<impl View> {
Ok(view! {
<div class="mt-6 space-y-6">
for review in reviews {
<article class="rounded-xl border border-slate-200 bg-white p-6">
Expand All @@ -274,5 +274,5 @@ pub async fn review_list(reviews: &[Review]) -> Result {
</article>
}
</div>
}
})
}
8 changes: 4 additions & 4 deletions benchmarks/topcoat/src/app/products.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use topcoat::{
Result,
context::{Cx, app_context},
router::{page, query_params},
view::{StaticClass, class, view},
view::{StaticClass, View, class, view},
};

use crate::{
Expand Down Expand Up @@ -35,14 +35,14 @@ struct ProductsQuery {
}

#[page]
async fn products(cx: &Cx) -> Result {
async fn products(cx: &Cx) -> Result<impl View> {
let query = query_params::<ProductsQuery>(cx)?;
let catalog = app_context::<Catalog>(cx);
let sort = normalize_sort(query.sort.as_deref());
let category = query.category.as_deref();
let page = catalog.page(query.page.unwrap_or(1), sort, category);

view! {
Ok(view! {
<div class="flex flex-wrap items-baseline justify-between gap-4">
<h1 class="text-3xl font-bold tracking-tight">"All products"</h1>
<p class="text-sm text-slate-500">
Expand Down Expand Up @@ -95,5 +95,5 @@ async fn products(cx: &Cx) -> Result {
category: category
)
}
}
})
}
Loading