feat: finalize the Hemx 0.4 core
CI / test (push) Has been cancelled

This commit is contained in:
tmk241
2026-09-02 17:28:40 +02:00
parent 1dc9734f16
commit a3c72e21db
15 changed files with 96 additions and 231 deletions
Generated
+68 -49
View File
@@ -80,9 +80,9 @@ checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.4.0" version = "1.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5add81bb678e6cb321aff7fa0dc7689ad82b112dbc032cea19f91d6b8e3582b9" checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273"
dependencies = [ dependencies = [
"find-msvc-tools", "find-msvc-tools",
"shlex", "shlex",
@@ -232,9 +232,9 @@ checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223"
[[package]] [[package]]
name = "find-msvc-tools" name = "find-msvc-tools"
version = "0.1.9" version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890"
[[package]] [[package]]
name = "futf" name = "futf"
@@ -248,21 +248,21 @@ dependencies = [
[[package]] [[package]]
name = "futures-core" name = "futures-core"
version = "0.3.33" version = "0.3.34"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7" checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e"
[[package]] [[package]]
name = "futures-task" name = "futures-task"
version = "0.3.33" version = "0.3.34"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109" checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd"
[[package]] [[package]]
name = "futures-util" name = "futures-util"
version = "0.3.33" version = "0.3.34"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa" checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-task", "futures-task",
@@ -297,37 +297,50 @@ checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
[[package]] [[package]]
name = "hemplate" name = "hemplate"
version = "0.2.0" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fbe24674c08ea9cb50edc015ebd364785a7e3985259dc02de1a20b7b2ba6365"
dependencies = [ dependencies = [
"hemplate-derive", "hemplate-derive",
"hemplate-runtime", "hemplate-runtime",
] ]
[[package]]
name = "hemplate-core"
version = "0.2.0"
dependencies = [
"hemplate-parser 0.1.0",
"thiserror",
"tree-sitter",
]
[[package]] [[package]]
name = "hemplate-core" name = "hemplate-core"
version = "0.2.0" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afe08241413edd4646684b396061b67e7fd17856f7e28d6765689612e2085303" checksum = "afe08241413edd4646684b396061b67e7fd17856f7e28d6765689612e2085303"
dependencies = [ dependencies = [
"hemplate-parser", "hemplate-parser 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"thiserror", "thiserror",
"tree-sitter", "tree-sitter",
] ]
[[package]] [[package]]
name = "hemplate-derive" name = "hemplate-derive"
version = "0.2.0" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ed77b2cc320137a6a68866f7aa8231292638f0b7c02f65cef221fe713fc2bad"
dependencies = [ dependencies = [
"hemplate-core", "hemplate-core 0.2.0",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.119", "syn 2.0.119",
] ]
[[package]]
name = "hemplate-parser"
version = "0.1.0"
dependencies = [
"tree-sitter",
"tree-sitter-hemplate 0.1.0",
]
[[package]] [[package]]
name = "hemplate-parser" name = "hemplate-parser"
version = "0.1.0" version = "0.1.0"
@@ -335,14 +348,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5418a7a1c7640f287133c512d400e2d1d2e083c86f9a6cb16501f36dd98636a2" checksum = "5418a7a1c7640f287133c512d400e2d1d2e083c86f9a6cb16501f36dd98636a2"
dependencies = [ dependencies = [
"tree-sitter", "tree-sitter",
"tree-sitter-hemplate", "tree-sitter-hemplate 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "hemplate-runtime" name = "hemplate-runtime"
version = "0.1.0" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8e235b36e44fe1174267df3ad0952a728afe4305edfbc8804a972b5f0121c06"
dependencies = [ dependencies = [
"thiserror", "thiserror",
] ]
@@ -373,7 +384,7 @@ dependencies = [
name = "hemx-build" name = "hemx-build"
version = "0.4.0" version = "0.4.0"
dependencies = [ dependencies = [
"hemplate-core", "hemplate-core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hemx-core", "hemx-core",
"quote", "quote",
"syn 2.0.119", "syn 2.0.119",
@@ -414,7 +425,7 @@ dependencies = [
[[package]] [[package]]
name = "hemx-test" name = "hemx-test"
version = "0.4.0" version = "0.5.0"
dependencies = [ dependencies = [
"axum", "axum",
"hemx-axum", "hemx-axum",
@@ -457,9 +468,9 @@ dependencies = [
[[package]] [[package]]
name = "http-body-util" name = "http-body-util"
version = "0.1.4" version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9f41fd6a08e4d4ec69df65976da761afd5ad5e58a9d4acb46bd1c953a9e3ff2" checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-core", "futures-core",
@@ -482,9 +493,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "1.11.0" version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d22053281f852e11534f5198498373cbb59295120a20771d90f7ed1897490a72" checksum = "27b501faa50e7a26c3d3560ca625132f4078a17771f4810baf70475ae48cbe43"
dependencies = [ dependencies = [
"bytes", "bytes",
"http", "http",
@@ -512,9 +523,9 @@ dependencies = [
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.14.0" version = "2.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" checksum = "07aa2048142242915a31d35844fb311e0e53fcca590c3a0a40dcf1b841fa09eb"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown", "hashbrown",
@@ -543,9 +554,9 @@ dependencies = [
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.33" version = "0.4.34"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6"
[[package]] [[package]]
name = "mac" name = "mac"
@@ -584,9 +595,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]] [[package]]
name = "mio" name = "mio"
version = "1.2.2" version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" checksum = "4b18443e9c262bfe8fa82f51666e2642c53393f7e5c27b3e1aeab922cff5b9d8"
dependencies = [ dependencies = [
"libc", "libc",
"wasi", "wasi",
@@ -866,7 +877,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 3.0.3", "syn 3.0.4",
] ]
[[package]] [[package]]
@@ -923,9 +934,9 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.15.2" version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" checksum = "b9be42f50aa861c555654aa3a37f52f4b1074bacf4e48fe0ef7fa584e80f1f0f"
[[package]] [[package]]
name = "socket2" name = "socket2"
@@ -992,9 +1003,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "3.0.3" version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" checksum = "e6275cddf4610d1775e6d1fe9469b2e77d0f39fd98fb7450901b821e0c53649f"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -1020,22 +1031,22 @@ dependencies = [
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "2.0.19" version = "2.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9" checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "2.0.19" version = "2.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd" checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 3.0.3", "syn 3.0.4",
] ]
[[package]] [[package]]
@@ -1060,7 +1071,7 @@ checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 3.0.3", "syn 3.0.4",
] ]
[[package]] [[package]]
@@ -1104,6 +1115,14 @@ dependencies = [
"tree-sitter-language", "tree-sitter-language",
] ]
[[package]]
name = "tree-sitter-hemplate"
version = "0.1.0"
dependencies = [
"cc",
"tree-sitter-language",
]
[[package]] [[package]]
name = "tree-sitter-hemplate" name = "tree-sitter-hemplate"
version = "0.1.0" version = "0.1.0"
@@ -1116,9 +1135,9 @@ dependencies = [
[[package]] [[package]]
name = "tree-sitter-language" name = "tree-sitter-language"
version = "0.1.7" version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "009994f150cc0cd50ff54917d5bc8bffe8cad10ca10d81c34da2ec421ae61782" checksum = "ca0d1bf6fdd806e43ae5198f82f527056d359def39e54e67a0f478ac09dac081"
[[package]] [[package]]
name = "typenum" name = "typenum"
@@ -1158,9 +1177,9 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]] [[package]]
name = "web_atoms" name = "web_atoms"
version = "0.2.5" version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "075474b12bcb3d2e3d4546580e9de478eeeead668a1761e2a8860c836b7ef297" checksum = "ba8b815c1b593dc0baf78dd0f4fc8fdb2de53198fb1163738093e9a311c33fb3"
dependencies = [ dependencies = [
"phf", "phf",
"phf_codegen", "phf_codegen",
-54
View File
@@ -17,7 +17,6 @@ pub(super) struct Resources {
pub(super) handle_forms: BTreeMap<String, String>, pub(super) handle_forms: BTreeMap<String, String>,
pub(super) handle_params: BTreeMap<String, BTreeSet<String>>, pub(super) handle_params: BTreeMap<String, BTreeSet<String>>,
pub(super) forms: BTreeMap<String, FormResource>, pub(super) forms: BTreeMap<String, FormResource>,
pub(super) atoms: BTreeMap<String, Resource>,
pub(super) classes: BTreeMap<String, ClassToken>, pub(super) classes: BTreeMap<String, ClassToken>,
pub(super) events: BTreeMap<String, EventToken>, pub(super) events: BTreeMap<String, EventToken>,
} }
@@ -101,12 +100,6 @@ impl Resources {
self.insert_slot(canonical, name, component.clone(), keyed)?; self.insert_slot(canonical, name, component.clone(), keyed)?;
} }
if let Some(name) = static_attr(&node.attrs, "data-hemx-atom") {
reject_unkeyed_loop(surface, node.scope, path, "atom", &name)?;
let canonical = canonical_symbol(root, path, &name);
self.insert_atom(canonical, name, component.clone())?;
}
if let Some(name) = static_attr(&node.attrs, "data-hemx-handle") { if let Some(name) = static_attr(&node.attrs, "data-hemx-handle") {
reject_unkeyed_loop(surface, node.scope, path, "handle", &name)?; reject_unkeyed_loop(surface, node.scope, path, "handle", &name)?;
let canonical = canonical_symbol(root, path, &name); let canonical = canonical_symbol(root, path, &name);
@@ -169,15 +162,6 @@ impl Resources {
insert_resource(&mut self.handles, "handle", symbol, name, component).map(|_| ()) insert_resource(&mut self.handles, "handle", symbol, name, component).map(|_| ())
} }
pub(super) fn insert_atom(
&mut self,
symbol: String,
name: String,
component: String,
) -> io::Result<()> {
insert_resource(&mut self.atoms, "atom", symbol, name, component).map(|_| ())
}
pub(super) fn insert_class( pub(super) fn insert_class(
&mut self, &mut self,
symbol: String, symbol: String,
@@ -576,21 +560,6 @@ impl Resources {
} }
out.push_str(&format!("{pad}}}\n\n")); out.push_str(&format!("{pad}}}\n\n"));
out.push_str(&format!(
"{pad}#[allow(non_upper_case_globals)]\n{pad}pub mod atoms {{\n"
));
for res in self
.atoms
.values()
.filter(|res| component_matches(res, component))
{
out.push_str(&format!(
"{inner}pub const {}: ::hemx::Atom<::std::string::String> = ::hemx::Atom::new({});\n",
res.ident, res.id
));
}
out.push_str(&format!("{pad}}}\n\n"));
out.push_str(&format!( out.push_str(&format!(
"{pad}#[allow(non_upper_case_globals)]\n{pad}pub mod classes {{\n" "{pad}#[allow(non_upper_case_globals)]\n{pad}pub mod classes {{\n"
)); ));
@@ -794,17 +763,6 @@ impl Resources {
res.id res.id
)); ));
} }
for res in self
.atoms
.values()
.filter(|res| component_matches(res, component))
{
out.push_str(&format!(
"{pad} (\"data-hemx-atom\", {}, {}),\n",
rust_str(&res.ident),
res.id
));
}
out.push_str(&format!("{pad}];\n")); out.push_str(&format!("{pad}];\n"));
} }
@@ -818,7 +776,6 @@ fn __hemx_lower_html(html: &str, table: &[(&str, &str, u32)]) -> ::std::string::
"data-hemx-handle" => "data-hemx-action", "data-hemx-handle" => "data-hemx-action",
"data-hemx-form" => "data-hemx-resource", "data-hemx-form" => "data-hemx-resource",
"data-hemx-revealed" => "data-hemx-revealed", "data-hemx-revealed" => "data-hemx-revealed",
"data-hemx-atom" => "data-hemx-resource",
_ => continue, _ => continue,
}; };
out = __hemx_replace_attr(out, attr, name, runtime_attr, *id); out = __hemx_replace_attr(out, attr, name, runtime_attr, *id);
@@ -899,7 +856,6 @@ fn __hemx_attr(tag: &str, attr: &str) -> Option<::std::string::String> {
.values() .values()
.map(|res| &res.component) .map(|res| &res.component)
.chain(self.handles.values().map(|res| &res.component)) .chain(self.handles.values().map(|res| &res.component))
.chain(self.atoms.values().map(|res| &res.component))
.chain(self.forms.values().map(|form| &form.resource.component)) .chain(self.forms.values().map(|form| &form.resource.component))
.chain(self.classes.values().map(|class| &class.component)) .chain(self.classes.values().map(|class| &class.component))
.chain(self.events.values().map(|event| &event.component)) .chain(self.events.values().map(|event| &event.component))
@@ -955,12 +911,6 @@ fn __hemx_attr(tag: &str, attr: &str) -> Option<::std::string::String> {
out.push_str(&format!("handle_param\t{handle_ident}\t{param}\n")); out.push_str(&format!("handle_param\t{handle_ident}\t{param}\n"));
} }
} }
for res in self.atoms.values() {
out.push_str(&format!(
"atom\t{}\t{}\t{}\n",
res.symbol, res.ident, res.id
));
}
for class in self.classes.values() { for class in self.classes.values() {
out.push_str(&format!( out.push_str(&format!(
"class\t{}\t{}\t{}\n", "class\t{}\t{}\t{}\n",
@@ -991,10 +941,6 @@ fn __hemx_attr(tag: &str, attr: &str) -> Option<::std::string::String> {
parts.push(1); parts.push(1);
parts.push(res.id); parts.push(res.id);
} }
for res in self.atoms.values() {
parts.push(3);
parts.push(res.id);
}
for form in self.forms.values() { for form in self.forms.values() {
parts.push(2); parts.push(2);
parts.push(form.resource.id); parts.push(form.resource.id);
-2
View File
@@ -42,11 +42,9 @@ pub(super) fn known_hemx_attr(name: &str) -> bool {
"data-hemx-root" "data-hemx-root"
| "data-hemx-sse" | "data-hemx-sse"
| "data-hemx-ws" | "data-hemx-ws"
| "data-hemx-st"
| "data-hemx-handle" | "data-hemx-handle"
| "data-hemx-slot" | "data-hemx-slot"
| "data-hemx-form" | "data-hemx-form"
| "data-hemx-atom"
| "data-hemx-key" | "data-hemx-key"
| "data-hemx-on" | "data-hemx-on"
| "data-hemx-pending-class" | "data-hemx-pending-class"
+7 -35
View File
@@ -589,10 +589,9 @@ mod tests {
io::ErrorKind::InvalidData io::ErrorKind::InvalidData
); );
for (kind, source) in [ let kind = "handle";
("atom", r#"<span data-hemx-atom="shared"></span>"#), let source = r#"<button data-hemx-handle="shared"></button>"#;
("handle", r#"<button data-hemx-handle="shared"></button>"#), {
] {
let first = let first =
surface_for_heml_source(Path::new("first.heml"), source.to_owned()).unwrap(); surface_for_heml_source(Path::new("first.heml"), source.to_owned()).unwrap();
let second = let second =
@@ -663,9 +662,6 @@ mod tests {
resources resources
.handles .handles
.insert("save".into(), resource("save", "page", 12)); .insert("save".into(), resource("save", "page", 12));
resources
.atoms
.insert("count".into(), resource("count", "page", 13));
resources.forms.insert( resources.forms.insert(
"profile".into(), "profile".into(),
FormResource { FormResource {
@@ -693,8 +689,6 @@ mod tests {
11, 11,
1, 1,
12, 12,
3,
13,
2, 2,
14, 14,
2, 2,
@@ -713,7 +707,6 @@ mod tests {
)); ));
assert!(generated.contains("pub const slot: SlotTarget")); assert!(generated.contains("pub const slot: SlotTarget"));
assert!(generated.contains("pub const save: ::hemx::Handle")); assert!(generated.contains("pub const save: ::hemx::Handle"));
assert!(generated.contains("pub const count: ::hemx::Atom"));
assert!(generated.contains("pub const profile: ::hemx::Form")); assert!(generated.contains("pub const profile: ::hemx::Form"));
assert!(generated.contains("\n pub mod targets {\n")); assert!(generated.contains("\n pub mod targets {\n"));
@@ -727,9 +720,6 @@ mod tests {
resources resources
.handles .handles
.insert("edit".into(), resource("edit", "row", 22)); .insert("edit".into(), resource("edit", "row", 22));
resources
.atoms
.insert("selection".into(), resource("selection", "row", 23));
resources resources
.slots .slots
.insert("child".into(), resource("child", "page", 24)); .insert("child".into(), resource("child", "page", 24));
@@ -788,17 +778,17 @@ mod tests {
let canonical_syms = resources.syms(); let canonical_syms = resources.syms();
assert_eq!( assert_eq!(
stable_id("generated-rs", &canonical_generated), stable_id("generated-rs", &canonical_generated),
3_787_638_288, 2_865_325_407,
"canonical generated Rust changed" "canonical generated Rust changed"
); );
assert_eq!( assert_eq!(
stable_id("generated-rs-global", &canonical_globals), stable_id("generated-rs-global", &canonical_globals),
1_112_484_789, 3_814_759_598,
"canonical global-export Rust changed" "canonical global-export Rust changed"
); );
assert_eq!( assert_eq!(
stable_id("generated-syms", &canonical_syms), stable_id("generated-syms", &canonical_syms),
984_222_700, 2_299_561_723,
"canonical symbol manifest changed" "canonical symbol manifest changed"
); );
} }
@@ -1090,7 +1080,7 @@ mod tests {
std::fs::create_dir_all(&templates).unwrap(); std::fs::create_dir_all(&templates).unwrap();
std::fs::write( std::fs::write(
templates.join("todo.heml"), templates.join("todo.heml"),
r#"<form class="todo-card" data-hemx-handle="create" data-hemx-form="new_todo"><input name="title" required><select name="labels" multiple><option value="urgent">Urgent</option></select><input name="__h" value="reserved"></form><button data-hemx-handle="delete" data-todo-id="7" data-hemx-on="click change">Delete</button><ul data-hemx-slot="todos"></ul><section data-hemx-atom="filter"></section>"#, r#"<form class="todo-card" data-hemx-handle="create" data-hemx-form="new_todo"><input name="title" required><select name="labels" multiple><option value="urgent">Urgent</option></select><input name="__h" value="reserved"></form><button data-hemx-handle="delete" data-todo-id="7" data-hemx-on="click change">Delete</button><ul data-hemx-slot="todos"></ul>"#,
) )
.unwrap(); .unwrap();
std::fs::write(templates.join("todo.css"), ".todo-card { display: block; }").unwrap(); std::fs::write(templates.join("todo.css"), ".todo-card { display: block; }").unwrap();
@@ -1141,8 +1131,6 @@ mod tests {
"pub const todo_id: ::hemx::ParamName = ::hemx::ParamName::new(\"todo_id\")" "pub const todo_id: ::hemx::ParamName = ::hemx::ParamName::new(\"todo_id\")"
)); ));
assert!(generated.contains("pub mod forms")); assert!(generated.contains("pub mod forms"));
assert!(generated.contains("pub mod atoms"));
assert!(generated.contains("pub const filter"));
assert!(generated.contains("pub mod events")); assert!(generated.contains("pub mod events"));
assert!(generated assert!(generated
.contains("pub const click: ::hemx::EventName = ::hemx::EventName::new(\"click\")")); .contains("pub const click: ::hemx::EventName = ::hemx::EventName::new(\"click\")"));
@@ -1196,10 +1184,6 @@ mod tests {
"form_field\tnew_todo\tlabels\tfalse\ttrue\n".to_owned(), "form_field\tnew_todo\tlabels\tfalse\ttrue\n".to_owned(),
"form_field\tnew_todo\ttitle\ttrue\tfalse\n".to_owned(), "form_field\tnew_todo\ttitle\ttrue\tfalse\n".to_owned(),
"handle_param\tdelete\ttodo_id\n".to_owned(), "handle_param\tdelete\ttodo_id\n".to_owned(),
format!(
"atom\ttodo.heml::filter\tfilter\t{}\n",
stable_id("atom", "todo.heml::filter")
),
"class\ttodo.css::todo-card\ttodo_card\ttodo-card\n".to_owned(), "class\ttodo.css::todo-card\ttodo_card\ttodo-card\n".to_owned(),
"class\ttodo.heml::todo-card\ttodo_card\ttodo-card\n".to_owned(), "class\ttodo.heml::todo-card\ttodo_card\ttodo-card\n".to_owned(),
"event\ttodo.heml::change\tchange\tchange\n".to_owned(), "event\ttodo.heml::change\tchange\tchange\n".to_owned(),
@@ -1611,8 +1595,6 @@ mod hemx {{
impl<K, T> KeyedSlot<K, T> {{ pub const fn new(_: u32) -> Self {{ Self(::std::marker::PhantomData) }} pub const fn id(self) -> ResourceId {{ ResourceId }} pub fn append_html(self, _: K, _: impl ::std::convert::Into<SafeHtml>) -> Effect {{ Effect }} pub fn prepend_html(self, _: K, _: impl ::std::convert::Into<SafeHtml>) -> Effect {{ Effect }} pub fn replace_html(self, _: K, _: impl ::std::convert::Into<SafeHtml>) -> Effect {{ Effect }} pub fn remove(self, _: K) -> Effect {{ Effect }} pub fn move_before(self, _: K, _: K) -> Effect {{ Effect }} pub fn move_to_end(self, _: K) -> Effect {{ Effect }} }} impl<K, T> KeyedSlot<K, T> {{ pub const fn new(_: u32) -> Self {{ Self(::std::marker::PhantomData) }} pub const fn id(self) -> ResourceId {{ ResourceId }} pub fn append_html(self, _: K, _: impl ::std::convert::Into<SafeHtml>) -> Effect {{ Effect }} pub fn prepend_html(self, _: K, _: impl ::std::convert::Into<SafeHtml>) -> Effect {{ Effect }} pub fn replace_html(self, _: K, _: impl ::std::convert::Into<SafeHtml>) -> Effect {{ Effect }} pub fn remove(self, _: K) -> Effect {{ Effect }} pub fn move_before(self, _: K, _: K) -> Effect {{ Effect }} pub fn move_to_end(self, _: K) -> Effect {{ Effect }} }}
#[derive(Clone, Copy)] pub struct Handle<T>(::std::marker::PhantomData<T>); #[derive(Clone, Copy)] pub struct Handle<T>(::std::marker::PhantomData<T>);
impl<T> Handle<T> {{ pub const fn new(_: u32) -> Self {{ Self(::std::marker::PhantomData) }} }} impl<T> Handle<T> {{ pub const fn new(_: u32) -> Self {{ Self(::std::marker::PhantomData) }} }}
#[derive(Clone, Copy)] pub struct Atom<T>(::std::marker::PhantomData<T>);
impl<T> Atom<T> {{ pub const fn new(_: u32) -> Self {{ Self(::std::marker::PhantomData) }} }}
#[derive(Clone, Copy)] pub struct Form<T>(::std::marker::PhantomData<T>); #[derive(Clone, Copy)] pub struct Form<T>(::std::marker::PhantomData<T>);
impl<T> Form<T> {{ pub const fn new(_: u32) -> Self {{ Self(::std::marker::PhantomData) }} }} impl<T> Form<T> {{ pub const fn new(_: u32) -> Self {{ Self(::std::marker::PhantomData) }} }}
#[derive(Clone, Copy)] pub struct CssClass(&'static str); #[derive(Clone, Copy)] pub struct CssClass(&'static str);
@@ -1891,12 +1873,6 @@ fn main() {{
"data-hemx-handle=\"delete\"", "data-hemx-handle=\"delete\"",
"ui::delete", "ui::delete",
), ),
(
"atom",
r#"<template h-for="todo in &self.todos"><span data-hemx-atom="selected">Selected</span></template>"#,
"data-hemx-atom=\"selected\"",
"ui::selected",
),
] { ] {
let base = test_dir(&format!("hemx-build-unkeyed-for-{case}-test")); let base = test_dir(&format!("hemx-build-unkeyed-for-{case}-test"));
let templates = base.join("templates"); let templates = base.join("templates");
@@ -1933,7 +1909,6 @@ fn main() {{
<li data-hemx-slot="todo_row"> <li data-hemx-slot="todo_row">
<template h-for="child in &todo.children" h-key="child.id"> <template h-for="child in &todo.children" h-key="child.id">
<button data-hemx-handle="delete">Delete</button> <button data-hemx-handle="delete">Delete</button>
<span data-hemx-atom="selected">Selected</span>
</template> </template>
</li> </li>
</template> </template>
@@ -1948,7 +1923,6 @@ fn main() {{
assert!(syms.contains("slot\ttodo.heml::todos\ttodos\t")); assert!(syms.contains("slot\ttodo.heml::todos\ttodos\t"));
assert!(syms.contains("slot\ttodo.heml::todo_row\ttodo_row\t")); assert!(syms.contains("slot\ttodo.heml::todo_row\ttodo_row\t"));
assert!(syms.contains("handle\ttodo.heml::delete\tdelete\t")); assert!(syms.contains("handle\ttodo.heml::delete\tdelete\t"));
assert!(syms.contains("atom\ttodo.heml::selected\tselected\t"));
assert!(syms.contains("slot\ttodo.heml::summary\tsummary\t")); assert!(syms.contains("slot\ttodo.heml::summary\tsummary\t"));
let generated = std::fs::read_to_string(out.join("hemx.generated.rs")).unwrap(); let generated = std::fs::read_to_string(out.join("hemx.generated.rs")).unwrap();
assert!(generated.contains("pub const todo_row: ::hemx::advanced::KeyedSlot")); assert!(generated.contains("pub const todo_row: ::hemx::advanced::KeyedSlot"));
@@ -2394,8 +2368,6 @@ mod hemx {{
impl<K, T> KeyedSlot<K, T> {{ pub const fn new(_: u32) -> Self {{ Self(::std::marker::PhantomData) }} pub const fn id(self) -> ResourceId {{ ResourceId }} pub fn append_html(self, _: K, _: impl ::std::convert::Into<SafeHtml>) -> Effect {{ Effect }} pub fn prepend_html(self, _: K, _: impl ::std::convert::Into<SafeHtml>) -> Effect {{ Effect }} pub fn replace_html(self, _: K, _: impl ::std::convert::Into<SafeHtml>) -> Effect {{ Effect }} pub fn remove(self, _: K) -> Effect {{ Effect }} pub fn move_before(self, _: K, _: K) -> Effect {{ Effect }} pub fn move_to_end(self, _: K) -> Effect {{ Effect }} }} impl<K, T> KeyedSlot<K, T> {{ pub const fn new(_: u32) -> Self {{ Self(::std::marker::PhantomData) }} pub const fn id(self) -> ResourceId {{ ResourceId }} pub fn append_html(self, _: K, _: impl ::std::convert::Into<SafeHtml>) -> Effect {{ Effect }} pub fn prepend_html(self, _: K, _: impl ::std::convert::Into<SafeHtml>) -> Effect {{ Effect }} pub fn replace_html(self, _: K, _: impl ::std::convert::Into<SafeHtml>) -> Effect {{ Effect }} pub fn remove(self, _: K) -> Effect {{ Effect }} pub fn move_before(self, _: K, _: K) -> Effect {{ Effect }} pub fn move_to_end(self, _: K) -> Effect {{ Effect }} }}
#[derive(Clone, Copy)] pub struct Handle<T>(::std::marker::PhantomData<T>); #[derive(Clone, Copy)] pub struct Handle<T>(::std::marker::PhantomData<T>);
impl<T> Handle<T> {{ pub const fn new(_: u32) -> Self {{ Self(::std::marker::PhantomData) }} }} impl<T> Handle<T> {{ pub const fn new(_: u32) -> Self {{ Self(::std::marker::PhantomData) }} }}
#[derive(Clone, Copy)] pub struct Atom<T>(::std::marker::PhantomData<T>);
impl<T> Atom<T> {{ pub const fn new(_: u32) -> Self {{ Self(::std::marker::PhantomData) }} }}
#[derive(Clone, Copy)] pub struct Form<T>(::std::marker::PhantomData<T>); #[derive(Clone, Copy)] pub struct Form<T>(::std::marker::PhantomData<T>);
impl<T> Form<T> {{ pub const fn new(_: u32) -> Self {{ Self(::std::marker::PhantomData) }} }} impl<T> Form<T> {{ pub const fn new(_: u32) -> Self {{ Self(::std::marker::PhantomData) }} }}
#[derive(Clone, Copy)] pub struct ComponentRef(&'static str); #[derive(Clone, Copy)] pub struct ComponentRef(&'static str);
-65
View File
@@ -14,27 +14,6 @@ pub const RUNTIME_ABI_VERSION: u32 = 1;
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub struct BuildFingerprint(pub u64); pub struct BuildFingerprint(pub u64);
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct AtomSnapshot {
pub id: u32,
pub bytes: Vec<u8>,
}
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
pub struct AtomState {
pub atoms: Vec<AtomSnapshot>,
}
impl AtomState {
pub fn to_postcard(&self) -> Result<Vec<u8>, postcard::Error> {
postcard::to_allocvec(self)
}
pub fn from_postcard(bytes: &[u8]) -> Result<Self, postcard::Error> {
postcard::from_bytes(bytes)
}
}
impl BuildFingerprint { impl BuildFingerprint {
pub const fn from_parts(parts: &[u32]) -> Self { pub const fn from_parts(parts: &[u32]) -> Self {
let mut hash = 0xcbf29ce484222325u64; let mut hash = 0xcbf29ce484222325u64;
@@ -51,7 +30,6 @@ impl BuildFingerprint {
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub enum ResourceKind { pub enum ResourceKind {
Slot, Slot,
Atom,
Handle, Handle,
Form, Form,
} }
@@ -669,7 +647,6 @@ fn write_ref(reference: &ResourceRef, out: &mut Vec<u8>) {
write_u8( write_u8(
match reference.resource.kind { match reference.resource.kind {
ResourceKind::Slot => 0, ResourceKind::Slot => 0,
ResourceKind::Atom => 1,
ResourceKind::Handle => 2, ResourceKind::Handle => 2,
ResourceKind::Form => 3, ResourceKind::Form => 3,
}, },
@@ -866,7 +843,6 @@ fn read_position(reader: &mut WireReader<'_>) -> Result<InsertPosition, WireErro
fn read_ref(reader: &mut WireReader<'_>) -> Result<ResourceRef, WireError> { fn read_ref(reader: &mut WireReader<'_>) -> Result<ResourceRef, WireError> {
let kind = match reader.read_u8()? { let kind = match reader.read_u8()? {
0 => ResourceKind::Slot, 0 => ResourceKind::Slot,
1 => ResourceKind::Atom,
2 => ResourceKind::Handle, 2 => ResourceKind::Handle,
3 => ResourceKind::Form, 3 => ResourceKind::Form,
_ => return Err(WireError::UnknownTag), _ => return Err(WireError::UnknownTag),
@@ -1126,47 +1102,6 @@ where
} }
} }
#[derive(Debug, Eq, PartialEq, Hash)]
pub struct Atom<T> {
id: ResourceId,
_marker: PhantomData<fn() -> T>,
}
impl<T> Clone for Atom<T> {
fn clone(&self) -> Self {
*self
}
}
impl<T> Copy for Atom<T> {}
impl<T> core::fmt::Display for Atom<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
self.id.id.fmt(f)
}
}
impl<T> Atom<T> {
pub const fn new(id: u32) -> Self {
Self {
id: ResourceId::new(ResourceKind::Atom, id),
_marker: PhantomData,
}
}
pub const fn id(self) -> ResourceId {
self.id
}
pub fn set(self, value: impl ToString) -> Effect {
Effect::Patch {
target: ResourceRef::unscoped(self.id),
mode: PatchMode::Morph,
html: SafeHtml::trusted(value.to_string()),
}
}
}
#[derive(Debug, Eq, PartialEq, Hash)] #[derive(Debug, Eq, PartialEq, Hash)]
pub struct Handle<I> { pub struct Handle<I> {
id: ResourceId, id: ResourceId,
+1 -1
View File
@@ -1,4 +1,4 @@
export type ResourceKind = "slot" | "atom" | "handle" | "form"; export type ResourceKind = "slot" | "handle" | "form";
export interface ResourceId { export interface ResourceId {
kind: ResourceKind; kind: ResourceKind;
+7 -1
View File
@@ -939,7 +939,13 @@
if (discriminant === 1) return read(); if (discriminant === 1) return read();
throw new Error(`unknown hemx option ${discriminant}`); throw new Error(`unknown hemx option ${discriminant}`);
}; };
const resource = () => ({ kind: enumValue(["slot", "atom", "handle", "form"], "hemx resource"), id: u32() }); const resource = () => {
const kind = u8();
if (kind === 0) return { kind: "slot", id: u32() };
if (kind === 2) return { kind: "handle", id: u32() };
if (kind === 3) return { kind: "form", id: u32() };
throw new Error(`unknown hemx resource ${kind}`);
};
const scope = () => { const scope = () => {
const kind = u8(); const kind = u8();
if (kind === 0) return null; if (kind === 0) return null;
-2
View File
@@ -365,8 +365,6 @@ fn runtime_has_no_mirrored_client_application_store() {
assert!(!source.contains("atomStore")); assert!(!source.contains("atomStore"));
assert!(!source.contains("bootstrapState")); assert!(!source.contains("bootstrapState"));
assert!(!source.contains("data-hemx-st"));
assert!(!source.contains("decodeAtomState"));
} }
#[test] #[test]
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "hemx-test" name = "hemx-test"
version = "0.4.0" version = "0.5.0"
edition.workspace = true edition.workspace = true
rust-version.workspace = true rust-version.workspace = true
license.workspace = true license.workspace = true
-1
View File
@@ -300,7 +300,6 @@ impl Error for HtmlInspectionError {}
fn resource_attribute(kind: ResourceKind) -> &'static str { fn resource_attribute(kind: ResourceKind) -> &'static str {
match kind { match kind {
ResourceKind::Slot => "data-hemx-resource", ResourceKind::Slot => "data-hemx-resource",
ResourceKind::Atom => "data-hemx-resource",
ResourceKind::Handle => "data-hemx-action", ResourceKind::Handle => "data-hemx-action",
ResourceKind::Form => "data-hemx-resource", ResourceKind::Form => "data-hemx-resource",
} }
+1 -5
View File
@@ -9,7 +9,7 @@ pub use html::{HtmlElement, HtmlInspectionError, HtmlInspector, HtmlSelection};
pub use process::{ProcessError, ProcessFailure, TestProcess, TestProcessBuilder}; pub use process::{ProcessError, ProcessFailure, TestProcess, TestProcessBuilder};
use hemx_core::{ use hemx_core::{
Atom, BuildFingerprint, Effect, EffectBatch, Form, GeneratedTarget, IntoEffect, KeyedSlot, BuildFingerprint, Effect, EffectBatch, Form, GeneratedTarget, IntoEffect, KeyedSlot,
ResourceId, ResourceRef, ScopeKey, Slot, ResourceId, ResourceRef, ScopeKey, Slot,
}; };
use std::future::Future; use std::future::Future;
@@ -465,10 +465,6 @@ impl EffectInspector {
self.has_resource(slot.id()) self.has_resource(slot.id())
} }
pub fn has_atom<T>(&self, atom: Atom<T>) -> bool {
self.has_resource(atom.id())
}
pub fn has_form<T>(&self, form: Form<T>) -> bool { pub fn has_form<T>(&self, form: Form<T>) -> bool {
self.has_resource(form.id()) self.has_resource(form.id())
} }
+3 -7
View File
@@ -1,7 +1,6 @@
use hemx_core::{ use hemx_core::{
Atom, BuildFingerprint, Effect, EffectBatch, Form, GeneratedTarget, HistoryMode, BuildFingerprint, Effect, EffectBatch, Form, GeneratedTarget, HistoryMode, InsertPosition,
InsertPosition, KeyedSlot, PatchMode, ResourceId, ResourceKind, ResourceRef, SafeHtml, KeyedSlot, PatchMode, ResourceId, ResourceKind, ResourceRef, SafeHtml, ScopeKey, Slot,
ScopeKey, Slot,
}; };
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
@@ -30,12 +29,10 @@ fn panic_text<T>(result: std::thread::Result<T>) -> String {
#[test] #[test]
fn inspects_tuple_effects() { fn inspects_tuple_effects() {
let count = Slot::<u32>::new(1); let count = Slot::<u32>::new(1);
let user = Atom::<String>::new(2);
let inspected = hemx_test::run(|value| (count.text(value), user.set("alice")), 42); let inspected = hemx_test::run(|value| count.text(value), 42);
assert!(inspected.has_slot(count)); assert!(inspected.has_slot(count));
assert!(inspected.has_atom(user));
assert!(inspected.contains(&Effect::Patch { assert!(inspected.contains(&Effect::Patch {
target: ResourceRef::unscoped(count.id()), target: ResourceRef::unscoped(count.id()),
mode: PatchMode::Morph, mode: PatchMode::Morph,
@@ -227,7 +224,6 @@ fn inspector_predicates_bind_operation_target_scope_kind_and_payload() {
assert!(!inspected.has_slot(Slot::<()>::new(99))); assert!(!inspected.has_slot(Slot::<()>::new(99)));
assert!(inspected.has_keyed_slot(KeyedSlot::<String, ()>::new(42))); assert!(inspected.has_keyed_slot(KeyedSlot::<String, ()>::new(42)));
assert!(!inspected.has_keyed_slot(KeyedSlot::<String, ()>::new(99))); assert!(!inspected.has_keyed_slot(KeyedSlot::<String, ()>::new(99)));
assert!(!inspected.has_atom(Atom::<()>::new(42)));
assert!(inspected.has_form(form)); assert!(inspected.has_form(form));
assert!(!inspected.has_form(Form::<()>::new(12))); assert!(!inspected.has_form(Form::<()>::new(12)));
+1 -1
View File
@@ -24,4 +24,4 @@ default = []
hemx-core = { version = "0.4.0", path = "../hemx-core" } hemx-core = { version = "0.4.0", path = "../hemx-core" }
hemx-derive = { version = "0.4.0", path = "../hemx-derive" } hemx-derive = { version = "0.4.0", path = "../hemx-derive" }
hemplate = { version = "0.2.0", default-features = false } hemplate = { version = "0.3.0", path = "../../hemplate/hemplate", default-features = false }
+6 -6
View File
@@ -13,9 +13,9 @@ pub use hemx_core::{
/// Generated metadata tokens used by macros, generated code, integrations, and tests. /// Generated metadata tokens used by macros, generated code, integrations, and tests.
/// ///
/// These stay addressable for compatibility, but ordinary app code should use generated /// These stay addressable for compatibility, but ordinary app code should use generated
/// helpers instead of naming raw handles, params, events, atoms, or component refs. /// helpers instead of naming raw handles, params, events, or component refs.
#[doc(hidden)] #[doc(hidden)]
pub use hemx_core::{Atom, ComponentRef, EventName, GeneratedTarget, Handle, ParamName}; pub use hemx_core::{ComponentRef, EventName, GeneratedTarget, Handle, ParamName};
pub use hemx_derive::{app, component, form, handler, surface}; pub use hemx_derive::{app, component, form, handler, surface};
/// Advanced/raw hemx primitives used by generated code, integrations, and tests. /// Advanced/raw hemx primitives used by generated code, integrations, and tests.
@@ -188,8 +188,8 @@ mod tests {
struct InlineView; struct InlineView;
impl hemplate::Hemplate for InlineView { impl hemplate::Hemplate for InlineView {
fn render_into(&self, out: &mut String) -> Result<(), hemplate::RenderError> { fn render_into(&self, out: &mut dyn core::fmt::Write) -> Result<(), hemplate::RenderError> {
out.push_str("<strong>ok</strong>"); out.write_str("<strong>ok</strong>")?;
Ok(()) Ok(())
} }
} }
@@ -197,8 +197,8 @@ mod tests {
struct HintTrackingView(Cell<bool>); struct HintTrackingView(Cell<bool>);
impl hemplate::Hemplate for HintTrackingView { impl hemplate::Hemplate for HintTrackingView {
fn render_into(&self, out: &mut String) -> Result<(), hemplate::RenderError> { fn render_into(&self, out: &mut dyn core::fmt::Write) -> Result<(), hemplate::RenderError> {
out.push_str("<strong>hinted</strong>"); out.write_str("<strong>hinted</strong>")?;
Ok(()) Ok(())
} }
+1 -1
View File
@@ -6,7 +6,7 @@ license.workspace = true
publish = false publish = false
[dependencies] [dependencies]
hemplate = { version = "0.2.0", default-features = false, features = ["derive"] } hemplate = { version = "0.3.0", path = "../../../hemplate/hemplate", default-features = false, features = ["derive"] }
hemx = { path = "../../hemx" } hemx = { path = "../../hemx" }
[build-dependencies] [build-dependencies]