clone

tiny dependency-free nostr libraries for plain html, each under 5kb and named for an element. public domain

Publish the latest main to GitHub Pages

Dami committed def2bdd
commit
def2bdd37c699269249d45f6d79c0009e70a53b0
parent
3907f34ef71afdc004134c25eee6317f9a1c2ff0
author
Dami <dami.etoile@gmail.com>
2 files changed, +129 -0
A.github/workflows/pages.yml32++++++++++
Ascripts/site.ts97++++++++++++++++++++++++++++++
A .github/workflows/pages.yml +32 -0
A scripts/site.ts +97 -0
@@ -0,0 +1,97 @@
1+// Builds the static site in _site/: every library, the bundle, the demos and a landing page.2+// Run `deno task bundle` first so dist/ exists.3+import { brotliCompressSync } from "node:zlib";4+import { copy } from "jsr:@std/fs@1/copy";5+6+const REPO = "FelineStateMachine/nobel";7+const groups: [string, string, [string, string, number][]][] = [8+ ["nonmetal", "the base: relays, signatures, hooks", [["hydrogen", "H", 1]]],9+ ["noble gases", "the core: data and transport", [["xenon", "Xe", 54], ["krypton", "Kr", 36], ["argon", "Ar", 18], ["helium", "He", 2], ["neon", "Ne", 10], ["radon", "Rn", 86], ["oganesson", "Og", 118]]],10+ ["halogens", "secrets and trust", [["fluorine", "F", 9], ["chlorine", "Cl", 17], ["iodine", "I", 53]]],11+ ["transition metals", "signed exchanges", [["gold", "Au", 79], ["mercury", "Hg", 80]]],12+ ["lanthanides", "visual presets", [["praseodymium", "Pr", 59], ["europium", "Eu", 63], ["cerium", "Ce", 58]]],13+];14+const prefix: Record<string, string> = { hydrogen: "nhy", fluorine: "nfl", iodine: "nio" };15+const root = new URL("../", import.meta.url), out = new URL("_site/", root);16+const esc = (s: string) => s.replace(/[&<>"]/g, (c) => `&#${c.charCodeAt(0)};`);17+const kb = (n: number) => (n / 1024).toFixed(1);18+19+await Deno.remove(out, { recursive: true }).catch(() => {});20+await Deno.mkdir(out, { recursive: true });21+for (const d of ["dist", "demo"]) await copy(new URL(d, root), new URL(d, out));22+23+let cells = "";24+for (const [group, about, libs] of groups) {25+ cells += `<section class="${group.split(" ")[0]}"><h2>${group} <small>${about}</small></h2><div class="row">`;26+ for (const [name, sym, z] of libs) {27+ const src = await Deno.readFile(new URL(`${name}/${name}.js`, root));28+ const head = (await Deno.readTextFile(new URL(`${name}/README.md`, root))).split("\n")[0];29+ const tagline = head.split(" - ").slice(1).join(" - ");30+ await Deno.mkdir(new URL(`${name}/`, out), { recursive: true });31+ await Deno.writeFile(new URL(`${name}/${name}.js`, out), src);32+ const p = prefix[name] ?? `n${sym.toLowerCase()}`;33+ cells += `<article><a class="doc" href="https://github.com/${REPO}/tree/main/${name}#readme">34+<span class="z">${z}</span><b class="sym">${sym}</b><span class="name">${name}</span><span class="tag">${esc(tagline)}</span></a>35+<span class="meta"><code>${p}-</code> ${kb(src.length)}/${kb(brotliCompressSync(src).length)}kb</span>36+<a class="src" href="${name}/${name}.js">${name}.js</a></article>`;37+ }38+ cells += `</div></section>`;39+}40+41+const min = await Deno.readFile(new URL("dist/nobel.min.js", root));42+const cdn = `https://cdn.jsdelivr.net/gh/${REPO}@main`, site = "https://felinestatemachine.github.io/nobel/";43+const html = `<!doctype html>44+<html lang="en">45+<head>46+<meta charset="utf-8">47+<meta name="viewport" content="width=device-width, initial-scale=1">48+<title>nobel: tiny nostr libraries for plain HTML</title>49+<meta name="description" content="A family of tiny, dependency-free nostr libraries for plain HTML, each named for an element.">50+<style>51+ :root { --ink:#1d1b16; --paper:#f4efe4; --line:#d8cfbd; --muted:#7a7263; color-scheme:light dark; }52+ @media (prefers-color-scheme:dark) { :root { --ink:#ece6d8; --paper:#171512; --line:#3a352c; --muted:#9c9384; } }53+ * { box-sizing:border-box; }54+ body { margin:0; background:var(--paper); color:var(--ink); font:15px/1.55 ui-serif, Georgia, serif; }55+ main { max-width:1080px; margin:0 auto; padding:48px 20px 80px; }56+ h1 { font:600 15px/1 ui-monospace, Menlo, monospace; letter-spacing:.14em; text-transform:uppercase; margin:0 0 10px; }57+ .lede { max-width:62ch; margin:0 0 32px; font-size:17px; }58+ h2 { font:600 12px/1 ui-monospace, Menlo, monospace; letter-spacing:.12em; text-transform:uppercase; margin:28px 0 10px; }59+ h2 small { color:var(--muted); letter-spacing:0; text-transform:none; font-weight:400; margin-left:.5em; }60+ .row { display:grid; grid-template-columns:repeat(auto-fill, minmax(150px, 1fr)); gap:8px; }61+ article { border:1px solid var(--line); border-top:4px solid var(--g); border-radius:6px; padding:10px 12px; display:flex; flex-direction:column; gap:6px; min-height:170px; }62+ .doc { color:inherit; text-decoration:none; display:flex; flex-direction:column; flex:1; }63+ .z { font:11px ui-monospace, Menlo, monospace; color:var(--muted); }64+ .sym { font:600 34px/1.1 ui-serif, Georgia, serif; color:var(--g); }65+ .name { font:600 13px ui-monospace, Menlo, monospace; }66+ .tag { font-size:13px; color:var(--muted); }67+ .meta, .src { font:11px ui-monospace, Menlo, monospace; color:var(--muted); }68+ .src { color:var(--g); }69+ .nonmetal { --g:#2f7d5b; } .noble { --g:#6a4fb3; } .halogens { --g:#b0452a; } .transition { --g:#a17a12; } .lanthanides { --g:#2d6fa3; }70+ pre { background:color-mix(in srgb, var(--ink) 6%, transparent); border:1px solid var(--line); border-radius:6px; padding:12px 14px; overflow:auto; font:13px/1.5 ui-monospace, Menlo, monospace; }71+ a { color:inherit; }72+ footer { margin-top:40px; color:var(--muted); font-size:13px; }73+</style>74+</head>75+<body>76+<main>77+ <h1>nobel</h1>78+ <p class="lede">Tiny nostr libraries for plain HTML, in the spirit of <a href="https://fixiproject.org">the fixi project</a>. Each one is a single dependency-free script under 5kb, named for an element, and they compose through DOM events. Pick the ones you need, or take them all.</p>79+ <pre>&lt;script src="${cdn}/hydrogen/hydrogen.js"&gt;&lt;/script&gt;80+&lt;script src="${cdn}/xenon/xenon.js"&gt;&lt;/script&gt;81+82+&lt;ol nhy-relay="wss://relay.example" nxe-filter='{"kinds":[1],"limit":20}'&gt;83+ &lt;template&gt;&lt;li&gt;{content}&lt;/li&gt;&lt;/template&gt;84+&lt;/ol&gt;</pre>85+ ${cells}86+ <h2>all of them <small>one file, ${kb(min.length)}kb minified, ${kb(brotliCompressSync(min).length)}kb brotli</small></h2>87+ <pre>&lt;script src="${site}dist/nobel.min.js"&gt;&lt;/script&gt;</pre>88+ <p>Or from this site: <a href="dist/nobel.js">dist/nobel.js</a>, <a href="dist/nobel.min.js">dist/nobel.min.js</a>. Load hydrogen before the libraries that use it, and the peers before xenon.</p>89+ <h2>demos <small>add ?relay=wss://... to each</small></h2>90+ <p><a href="demo/">feed</a>, <a href="demo/iodine.html">private messages</a>, <a href="demo/oganesson.html">presence, typing, cursors</a>, <a href="demo/lanthanides.html">profiles and theme</a>, <a href="demo/europium.html">note embeds</a></p>91+ <footer>Always the latest <code>main</code>. <a href="https://github.com/${REPO}">Source on GitHub</a>, released into the public domain (Unlicense).</footer>92+</main>93+</body>94+</html>95+`;96+await Deno.writeTextFile(new URL("index.html", out), html);97+console.log(`_site/ built: ${groups.flatMap((g) => g[2]).length} libraries`);