webnek 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.mjs +2 -1
- package/package.json +1 -1
- package/template/build.rs +118 -41
- package/template/gitignore +8 -0
- package/template/src/client/{index.ts → index.js} +5 -5
- package/template/src/routes/page.rs +2 -2
package/bin/cli.mjs
CHANGED
|
@@ -101,7 +101,8 @@ function copyTemplate(from, to, vars) {
|
|
|
101
101
|
for (const name of readdirSync(from)) {
|
|
102
102
|
if (name === ".gitkeep" && existsSync(join(to, name))) continue;
|
|
103
103
|
const src = join(from, name);
|
|
104
|
-
|
|
104
|
+
let destName = name.endsWith(".tmpl") ? name.slice(0, -5) : name;
|
|
105
|
+
if (name === "gitignore") destName = ".gitignore";
|
|
105
106
|
const dest = join(to, destName);
|
|
106
107
|
if (statSync(src).isDirectory()) {
|
|
107
108
|
copyTemplate(src, dest, vars);
|
package/package.json
CHANGED
package/template/build.rs
CHANGED
|
@@ -1,53 +1,111 @@
|
|
|
1
1
|
//! Compile CSS and client JS into OUT_DIR on every `cargo build`.
|
|
2
|
+
//! Tailwind lives in ~/.cargo/webnek/cache (no project node_modules).
|
|
2
3
|
|
|
3
4
|
use std::env;
|
|
4
5
|
use std::fs;
|
|
5
6
|
use std::path::{Path, PathBuf};
|
|
6
|
-
use std::process::Command;
|
|
7
|
+
use std::process::{Command, Stdio};
|
|
8
|
+
|
|
9
|
+
const TW: &str = "4.3.3";
|
|
7
10
|
|
|
8
11
|
fn main() {
|
|
9
12
|
println!("cargo:rerun-if-changed=src/styles.css");
|
|
13
|
+
println!("cargo:rerun-if-changed=src/client/index.js");
|
|
10
14
|
println!("cargo:rerun-if-changed=src/client/index.ts");
|
|
11
15
|
|
|
16
|
+
let manifest = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".into()));
|
|
12
17
|
let out = PathBuf::from(env::var("OUT_DIR").unwrap());
|
|
13
|
-
write_css(&out.join("styles.css"));
|
|
14
|
-
write_js(&out.join("client.js"));
|
|
18
|
+
write_css(&manifest, &out.join("styles.css"));
|
|
19
|
+
write_js(&manifest, &out.join("client.js"));
|
|
15
20
|
}
|
|
16
21
|
|
|
17
|
-
fn
|
|
18
|
-
let
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
fn cache_dir() -> PathBuf {
|
|
23
|
+
if let Ok(h) = env::var("CARGO_HOME") {
|
|
24
|
+
PathBuf::from(h).join("webnek").join("cache")
|
|
25
|
+
} else if let Ok(h) = env::var("HOME") {
|
|
26
|
+
PathBuf::from(h).join(".cargo").join("webnek").join("cache")
|
|
27
|
+
} else {
|
|
28
|
+
PathBuf::from(".webnek-cache")
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
fn ensure_tailwind(cache: &Path) -> bool {
|
|
33
|
+
let _ = fs::create_dir_all(cache);
|
|
34
|
+
let pkg = cache.join("package.json");
|
|
35
|
+
if !pkg.exists() {
|
|
36
|
+
let _ = fs::write(&pkg, "{\"name\":\"webnek-cache\",\"private\":true}");
|
|
37
|
+
}
|
|
38
|
+
let cli = cache.join("node_modules/@tailwindcss/cli/dist/index.mjs");
|
|
39
|
+
let tw = cache.join("node_modules/tailwindcss");
|
|
40
|
+
if cli.exists() && tw.exists() {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
let spec_tw = format!("tailwindcss@{TW}");
|
|
44
|
+
let spec_cli = format!("@tailwindcss/cli@{TW}");
|
|
45
|
+
run(
|
|
46
|
+
cache,
|
|
47
|
+
"bun",
|
|
48
|
+
&["add", &spec_tw, &spec_cli],
|
|
49
|
+
None,
|
|
29
50
|
) || run(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
) {
|
|
51
|
+
cache,
|
|
52
|
+
"npm",
|
|
53
|
+
&["install", &spec_tw, &spec_cli],
|
|
54
|
+
None,
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
fn link_node_modules(manifest: &Path, cache: &Path) -> bool {
|
|
59
|
+
let dest = manifest.join("node_modules");
|
|
60
|
+
let src = cache.join("node_modules");
|
|
61
|
+
if dest.exists() || !src.exists() {
|
|
62
|
+
return dest.exists();
|
|
63
|
+
}
|
|
64
|
+
#[cfg(unix)]
|
|
65
|
+
{
|
|
66
|
+
std::os::unix::fs::symlink(&src, &dest).is_ok()
|
|
67
|
+
}
|
|
68
|
+
#[cfg(not(unix))]
|
|
69
|
+
{
|
|
70
|
+
std::os::windows::fs::symlink_dir(&src, &dest).is_ok()
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
fn write_css(manifest: &Path, dest: &Path) {
|
|
75
|
+
let cache = cache_dir();
|
|
76
|
+
if !ensure_tailwind(&cache) {
|
|
77
|
+
fail();
|
|
78
|
+
}
|
|
79
|
+
let _ = link_node_modules(manifest, &cache);
|
|
80
|
+
let entry = cache.join("node_modules/@tailwindcss/cli/dist/index.mjs");
|
|
81
|
+
let node_modules = cache.join("node_modules");
|
|
82
|
+
let out = dest.to_string_lossy().into_owned();
|
|
83
|
+
let args = [
|
|
84
|
+
entry.to_str().unwrap_or(""),
|
|
85
|
+
"-i",
|
|
86
|
+
"src/styles.css",
|
|
87
|
+
"-o",
|
|
88
|
+
&out,
|
|
89
|
+
"--minify",
|
|
90
|
+
];
|
|
91
|
+
let ok = run(manifest, "bun", &args, Some(&node_modules))
|
|
92
|
+
|| run(manifest, "node", &args, Some(&node_modules));
|
|
93
|
+
|
|
94
|
+
let css = fs::read_to_string(dest).unwrap_or_default();
|
|
95
|
+
if ok && compiled(&css) {
|
|
41
96
|
return;
|
|
42
97
|
}
|
|
43
|
-
|
|
44
|
-
.unwrap_or_else(|_| "/* styles.css: install bun or npx to compile Tailwind */\n".into());
|
|
45
|
-
let _ = fs::write(dest, fallback);
|
|
98
|
+
fail();
|
|
46
99
|
}
|
|
47
100
|
|
|
48
|
-
fn write_js(dest: &Path) {
|
|
49
|
-
let
|
|
101
|
+
fn write_js(manifest: &Path, dest: &Path) {
|
|
102
|
+
let js = manifest.join("src/client/index.js");
|
|
103
|
+
if js.exists() && fs::copy(&js, dest).is_ok() {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
let out = dest.to_string_lossy().into_owned();
|
|
50
107
|
if run(
|
|
108
|
+
manifest,
|
|
51
109
|
"bunx",
|
|
52
110
|
&[
|
|
53
111
|
"esbuild",
|
|
@@ -55,9 +113,11 @@ fn write_js(dest: &Path) {
|
|
|
55
113
|
"--bundle",
|
|
56
114
|
"--format=esm",
|
|
57
115
|
"--outfile",
|
|
58
|
-
out,
|
|
116
|
+
&out,
|
|
59
117
|
],
|
|
118
|
+
None,
|
|
60
119
|
) || run(
|
|
120
|
+
manifest,
|
|
61
121
|
"npx",
|
|
62
122
|
&[
|
|
63
123
|
"--yes",
|
|
@@ -66,19 +126,36 @@ fn write_js(dest: &Path) {
|
|
|
66
126
|
"--bundle",
|
|
67
127
|
"--format=esm",
|
|
68
128
|
"--outfile",
|
|
69
|
-
out,
|
|
129
|
+
&out,
|
|
70
130
|
],
|
|
131
|
+
None,
|
|
71
132
|
) {
|
|
72
133
|
return;
|
|
73
134
|
}
|
|
74
|
-
let
|
|
75
|
-
|
|
135
|
+
let _ = fs::write(dest, "// client\n");
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
fn compiled(css: &str) -> bool {
|
|
139
|
+
let t = css.trim_start();
|
|
140
|
+
!t.is_empty()
|
|
141
|
+
&& !t.starts_with("@import \"tailwindcss\"")
|
|
142
|
+
&& !t.starts_with("@import 'tailwindcss'")
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
fn run(dir: &Path, bin: &str, args: &[&str], node_path: Option<&Path>) -> bool {
|
|
146
|
+
let mut cmd = Command::new(bin);
|
|
147
|
+
cmd.args(args)
|
|
148
|
+
.current_dir(dir)
|
|
149
|
+
.stdin(Stdio::null());
|
|
150
|
+
if let Some(p) = node_path {
|
|
151
|
+
cmd.env("NODE_PATH", p);
|
|
152
|
+
}
|
|
153
|
+
cmd.status().map(|s| s.success()).unwrap_or(false)
|
|
76
154
|
}
|
|
77
155
|
|
|
78
|
-
fn
|
|
79
|
-
|
|
80
|
-
.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
.unwrap_or(false)
|
|
156
|
+
fn fail() -> ! {
|
|
157
|
+
panic!(
|
|
158
|
+
"webnek: could not compile src/styles.css.\n\
|
|
159
|
+
Install bun or npm, then run `cargo build` again."
|
|
160
|
+
);
|
|
84
161
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
console.log("⚡ [webnek] Client island initialized");
|
|
2
|
-
|
|
3
1
|
document.addEventListener("click", (e) => {
|
|
4
|
-
const
|
|
2
|
+
const el = e.target;
|
|
3
|
+
if (!(el instanceof Element)) return;
|
|
4
|
+
const target = el.closest("[data-action]");
|
|
5
5
|
if (!target) return;
|
|
6
6
|
|
|
7
7
|
const action = target.getAttribute("data-action");
|
|
@@ -14,6 +14,6 @@ document.addEventListener("click", (e) => {
|
|
|
14
14
|
if (action === "dec") val -= 1;
|
|
15
15
|
if (action === "reset") val = 0;
|
|
16
16
|
|
|
17
|
-
counterEl.textContent = val
|
|
18
|
-
if (doubleEl) doubleEl.textContent = (val * 2)
|
|
17
|
+
counterEl.textContent = String(val);
|
|
18
|
+
if (doubleEl) doubleEl.textContent = String(val * 2);
|
|
19
19
|
});
|
|
@@ -44,14 +44,14 @@ pub fn home_page() -> View {
|
|
|
44
44
|
<div className="flex gap-2 pb-1">
|
|
45
45
|
<button
|
|
46
46
|
data-action="dec"
|
|
47
|
-
className="w-10 h-10 border border-line bg-paper text-ink text-lg leading-none hover:bg-white transition-colors"
|
|
47
|
+
className="w-10 h-10 border border-line bg-paper text-ink text-lg leading-none cursor-pointer hover:bg-white transition-colors"
|
|
48
48
|
onClick={move || set_count.update(|c| *c -= 1)}
|
|
49
49
|
>
|
|
50
50
|
"−"
|
|
51
51
|
</button>
|
|
52
52
|
<button
|
|
53
53
|
data-action="inc"
|
|
54
|
-
className="w-10 h-10 bg-ink text-paper text-lg leading-none hover:bg-patina transition-colors"
|
|
54
|
+
className="w-10 h-10 bg-ink text-paper text-lg leading-none cursor-pointer hover:bg-patina transition-colors"
|
|
55
55
|
onClick={move || set_count.update(|c| *c += 1)}
|
|
56
56
|
>
|
|
57
57
|
"+"
|