aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--flake.nix96
-rw-r--r--lib/xesite_templates/Cargo.toml3
-rw-r--r--lib/xesite_templates/src/lib.rs37
-rw-r--r--src/frontend/.gitignore1
-rwxr-xr-xsrc/frontend/build.sh1
-rw-r--r--src/frontend/build.ts25
-rw-r--r--src/frontend/components/ConvSnippet.tsx56
-rw-r--r--src/frontend/components/MastodonShareButton.tsx76
-rw-r--r--src/frontend/components/WASITerm.tsx83
-rw-r--r--src/frontend/deno.lock32
-rw-r--r--src/frontend/deps.ts10
-rw-r--r--src/frontend/import_map.json9
-rw-r--r--src/frontend/mastodon_share_button.tsx64
-rw-r--r--src/frontend/state.js5
-rw-r--r--src/frontend/wasiterm.tsx53
-rw-r--r--src/tmpl/blog.rs11
-rw-r--r--static/wasm/.gitignore1
-rw-r--r--static/xeact/.gitignore1
-rw-r--r--wasi/.gitignore2
-rw-r--r--wasi/build.zig15
-rw-r--r--wasi/src/hello.zig5
22 files changed, 390 insertions, 197 deletions
diff --git a/Cargo.lock b/Cargo.lock
index c8331d4..0e67412 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3649,6 +3649,7 @@ name = "xesite_templates"
version = "0.1.0"
dependencies = [
"maud",
+ "serde_json",
"uuid",
"xesite_types",
]
diff --git a/flake.nix b/flake.nix
index 3000fa9..0e51a2b 100644
--- a/flake.nix
+++ b/flake.nix
@@ -4,7 +4,7 @@
inputs = {
nixpkgs.url = "nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
-
+
flake-compat = {
url = "github:edolstra/flake-compat";
flake = false;
@@ -93,50 +93,60 @@
'';
};
- frontend = let
- build = { entrypoint, name ? entrypoint, minify ? true }:
- pkgs.deno2nix.mkBundled {
- pname = "xesite-frontend-${name}";
- inherit (bin) version;
-
- src = ./src/frontend;
- lockfile = ./src/frontend/deno.lock;
-
- output = "${entrypoint}.js";
- outPath = "static/js";
- entrypoint = "./${entrypoint}.tsx";
- importMap = "./import_map.json";
- inherit minify;
- };
- share-button = build { entrypoint = "mastodon_share_button"; };
- wasiterm = build { entrypoint = "wasiterm"; };
- in pkgs.symlinkJoin {
- name = "xesite-frontend-${bin.version}";
- paths = [ share-button wasiterm ];
+ frontend = pkgs.stdenv.mkDerivation rec {
+ pname = "xesite-frontend";
+ inherit (bin) version;
+ dontUnpack = true;
+ src = ./src/frontend;
+ buildInputs = with pkgs; [ deno jq nodePackages.uglify-js ];
+ ESBUILD_BINARY_PATH = "${pkgs.esbuild}/bin/esbuild";
+
+ buildPhase = ''
+ export DENO_DIR="$(pwd)/.deno2nix"
+ mkdir -p $DENO_DIR
+ ln -s "${pkgs.deno2nix.internal.mkDepsLink ./src/frontend/deno.lock}" $(deno info --json | jq -r .modulesCache)
+
+ mkdir -p dist
+ export WRITE_TO=$(pwd)/dist
+
+ pushd $(pwd)
+ cd $src
+ deno run -A ./build.ts
+ popd
+ '';
+
+ installPhase = ''
+ mkdir -p $out/static/xeact
+ cp -vrf dist/* $out/static/xeact
+ '';
};
iosevka = pkgs.stdenvNoCC.mkDerivation {
name = "xesite-iosevka";
- buildInputs = with pkgs; [ python311Packages.brotli python311Packages.fonttools ];
+ buildInputs = with pkgs; [
+ python311Packages.brotli
+ python311Packages.fonttools
+ ];
dontUnpack = true;
- buildPhase =
- ''
- mkdir -p out
- ${pkgs.unzip}/bin/unzip ${self.inputs.iosevka.packages.${system}.default}/ttf.zip
- for ttf in ttf/*.ttf; do
- cp $ttf out
- name=`basename -s .ttf $ttf`
- pyftsubset \
- $ttf \
- --output-file=out/"$name".woff2 \
- --flavor=woff2 \
- --layout-features=* \
- --no-hinting \
- --desubroutinize \
- --unicodes="U+0000-00A0,U+00A2-00A9,U+00AC-00AE,U+00B0-00B7,U+00B9-00BA,U+00BC-00BE,U+00D7,U+00F7,U+2000-206F,U+2074,U+20AC,U+2122,U+2190-21BB,U+2212,U+2215,U+F8FF,U+FEFF,U+FFFD"
- done
-
- '';
+ buildPhase = ''
+ mkdir -p out
+ ${pkgs.unzip}/bin/unzip ${
+ self.inputs.iosevka.packages.${system}.default
+ }/ttf.zip
+ for ttf in ttf/*.ttf; do
+ cp $ttf out
+ name=`basename -s .ttf $ttf`
+ pyftsubset \
+ $ttf \
+ --output-file=out/"$name".woff2 \
+ --flavor=woff2 \
+ --layout-features=* \
+ --no-hinting \
+ --desubroutinize \
+ --unicodes="U+0000-00A0,U+00A2-00A9,U+00AC-00AE,U+00B0-00B7,U+00B9-00BA,U+00BC-00BE,U+00D7,U+00F7,U+2000-206F,U+2074,U+20AC,U+2122,U+2190-21BB,U+2212,U+2215,U+F8FF,U+FEFF,U+FFFD"
+ done
+
+ '';
installPhase = ''
mkdir -p $out/static/css/iosevka
cp out/* $out/static/css/iosevka
@@ -212,9 +222,8 @@
# frontend
deno
nodePackages.uglify-js
-
- # dependency manager
- niv
+ esbuild
+ zig
# tools
ispell
@@ -224,6 +233,7 @@
SITE_PREFIX = "devel.";
CLACK_SET = "Ashlynn,Terry Davis,Dennis Ritchie";
+ ESBUILD_BINARY_PATH = "${pkgs.esbuild}/bin/esbuild";
RUST_LOG = "debug";
RUST_BACKTRACE = "1";
GITHUB_SHA = "devel";
diff --git a/lib/xesite_templates/Cargo.toml b/lib/xesite_templates/Cargo.toml
index fc852b0..dbfa1d3 100644
--- a/lib/xesite_templates/Cargo.toml
+++ b/lib/xesite_templates/Cargo.toml
@@ -6,6 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
+serde_json = "1"
uuid = { version = "1", features = [ "v4" ] }
xesite_types = { path = "../xesite_types" }
@@ -13,4 +14,4 @@ xesite_types = { path = "../xesite_types" }
[dependencies.maud]
git = "https://github.com/Xe/maud"
rev = "a40596c42c7603cc4610bbeddea04c4bd8b312d9"
-features = ["axum"] \ No newline at end of file
+features = ["axum"]
diff --git a/lib/xesite_templates/src/lib.rs b/lib/xesite_templates/src/lib.rs
index 767ac45..b1945e9 100644
--- a/lib/xesite_templates/src/lib.rs
+++ b/lib/xesite_templates/src/lib.rs
@@ -228,3 +228,40 @@ pub fn toot_embed(u: User, t: Toot) -> Markup {
}
}
}
+
+pub fn xeact_component(name: &str, data: serde_json::Value) -> Markup {
+ let uuid = uuid::Uuid::new_v4();
+ let uuid = format!("{uuid}").replace("-", "");
+
+ let script = PreEscaped(format!(
+ r#"
+<script type="module">
+import Component from "/static/xeact/{name}.js";
+
+const g = (name) => document.getElementById(name);
+const x = (elem) => {{
+ while (elem.lastChild) {{
+ elem.removeChild(elem.lastChild);
+ }}
+}};
+
+const root = g("{uuid}");
+x(g);
+
+root.appendChild(Component({data}))
+</script>
+"#,
+ data=serde_json::to_string(&data).unwrap(),
+ ));
+
+ html! {
+ div id=(uuid) {
+ noscript {
+ div.warning {
+ (conv("Aoi".into(), "coffee".into(), PreEscaped("This dynamic component requires JavaScript to function, sorry!".to_string())))
+ }
+ }
+ }
+ (script)
+ }
+}
diff --git a/src/frontend/.gitignore b/src/frontend/.gitignore
new file mode 100644
index 0000000..5f98501
--- /dev/null
+++ b/src/frontend/.gitignore
@@ -0,0 +1 @@
+dist/*.js
diff --git a/src/frontend/build.sh b/src/frontend/build.sh
index 33577ae..ef3fed1 100755
--- a/src/frontend/build.sh
+++ b/src/frontend/build.sh
@@ -9,4 +9,3 @@ set -e
export RUST_LOG=info
denobuild ./mastodon_share_button.tsx ../../static/js/mastodon_share_button.js
-denobuild ./wasiterm.tsx ../../static/js/wasiterm.js
diff --git a/src/frontend/build.ts b/src/frontend/build.ts
new file mode 100644
index 0000000..70c8b2b
--- /dev/null
+++ b/src/frontend/build.ts
@@ -0,0 +1,25 @@
+import * as esbuild from "@esbuild";
+import { denoPlugin } from "@esbuild/deno";
+
+const result = await esbuild.build({
+ plugins: [denoPlugin({
+ importMapURL: new URL("./import_map.json", import.meta.url),
+ })],
+ entryPoints: [
+ "./components/ConvSnippet.tsx",
+ "./components/MastodonShareButton.tsx",
+ "./components/WASITerm.tsx",
+ ],
+ outdir: Deno.env.get("WRITE_TO")
+ ? Deno.env.get("WRITE_TO")
+ : "../../static/xeact",
+ bundle: true,
+ splitting: true,
+ format: "esm",
+ //minifyWhitespace: true,
+ inject: ["xeact"],
+ jsxFactory: "h",
+});
+console.log(result.outputFiles);
+
+esbuild.stop();
diff --git a/src/frontend/components/ConvSnippet.tsx b/src/frontend/components/ConvSnippet.tsx
index 02b2121..375ed9a 100644
--- a/src/frontend/components/ConvSnippet.tsx
+++ b/src/frontend/components/ConvSnippet.tsx
@@ -1,27 +1,43 @@
+// @jsxImportSource xeact
+// @jsxRuntime automatic
+
export interface ConvSnippetProps {
- name: string;
- mood: string;
- children: HTMLElement[];
+ name: string;
+ mood: string;
+ children: HTMLElement[];
}
-const ConvSnippet = ({name, mood, children}: ConvSnippetProps) => {
- const nameLower = name.toLowerCase();
- name = name.replace(" ", "_");
+const ConvSnippet = ({ name, mood, children }: ConvSnippetProps) => {
+ const nameLower = name.toLowerCase();
+ name = name.replace(" ", "_");
- return (
- <div className="conversation">
- <div className="conversation-standalone">
- <picture>
- <source type="image/avif" srcset={`https://cdn.xeiaso.net/file/christine-static/stickers/${nameLower}/${mood}.avif`} />
- <source type="image/webp" srcset={`https://cdn.xeiaso.net/file/christine-static/stickers/${nameLower}/${mood}.webp`} />
- <img style="max-height:4.5rem" alt={`${name} is ${mood}`} loading="lazy" src={`https://cdn.xeiaso.net/file/christine-static/stickers/${nameLower}/${mood}.png`} />
- </picture>
- </div>
- <div className="conversation-chat">
- &lt;<a href={`/characters#${nameLower}`}><b>{name}</b></a>&gt; {children}
- </div>
- </div>
- );
+ return (
+ <div className="conversation">
+ <div className="conversation-standalone">
+ <picture>
+ <source
+ type="image/avif"
+ srcset={`https://cdn.xeiaso.net/file/christine-static/stickers/${nameLower}/${mood}.avif`}
+ />
+ <source
+ type="image/webp"
+ srcset={`https://cdn.xeiaso.net/file/christine-static/stickers/${nameLower}/${mood}.webp`}
+ />
+ <img
+ style="max-height:4.5rem"
+ alt={`${name} is ${mood}`}
+ loading="lazy"
+ src={`https://cdn.xeiaso.net/file/christine-static/stickers/${nameLower}/${mood}.png`}
+ />
+ </picture>
+ </div>
+ <div className="conversation-chat">
+ &lt;<a href={`/characters#${nameLower}`}>
+ <b>{name}</b>
+ </a>&gt; {children}
+ </div>
+ </div>
+ );
};
export default ConvSnippet;
diff --git a/src/frontend/components/MastodonShareButton.tsx b/src/frontend/components/MastodonShareButton.tsx
new file mode 100644
index 0000000..03fe596
--- /dev/null
+++ b/src/frontend/components/MastodonShareButton.tsx
@@ -0,0 +1,76 @@
+// @jsxImportSource xeact
+// @jsxRuntime automatic
+
+import { u } from "xeact";
+
+export interface MastodonShareButtonProps {
+ title: string;
+ url: string;
+ series?: string;
+ tags: string;
+}
+
+export default function MastodonShareButton(
+ { title, url = u(), series, tags }: MastodonShareButtonProps,
+) {
+ let defaultURL = localStorage["mastodon_instance"];
+
+ if (defaultURL == undefined) {
+ defaultURL = "";
+ }
+
+ const tootTemplate = `${title}
+
+${url}
+
+${series ? "#" + series + " " : ""}${
+ tags ? tags.map((x) => "#" + x).join(" ") : ""
+ } @cadey@pony.social`;
+
+ const instanceBox = (
+ <input
+ type="text"
+ placeholder="https://pony.social"
+ value={defaultURL}
+ />
+ );
+ const tootBox = (
+ <textarea rows={6} cols={40}>
+ {tootTemplate}
+ </textarea>
+ );
+
+ return (
+ <div>
+ <details>
+ <summary>Share on Mastodon</summary>
+ <span>{"Instance URL (https://mastodon.example)"}</span>
+ <br />
+ {instanceBox}
+ <br />
+ {tootBox}
+ <br />
+ <button
+ onClick={() => {
+ let instanceURL = instanceBox.value;
+
+ if (!instanceURL.startsWith("https://")) {
+ instanceURL = `https://${instanceURL}`;
+ }
+
+ localStorage["mastodon_instance"] = instanceURL;
+ const text = tootBox.value;
+ const mastodonURL = u(instanceURL + "/share", {
+ text,
+ visibility: "public",
+ });
+ console.log({ text, mastodonURL });
+ window.open(mastodonURL, "_blank");
+ }}
+ >
+ Share
+ </button>
+ </details>
+ </div>
+ );
+}
diff --git a/src/frontend/components/WASITerm.tsx b/src/frontend/components/WASITerm.tsx
new file mode 100644
index 0000000..5f7e7f9
--- /dev/null
+++ b/src/frontend/components/WASITerm.tsx
@@ -0,0 +1,83 @@
+// @jsxImportSource xeact
+// @jsxRuntime automatic
+
+import { t, x } from "xeact";
+import Terminal from "@xterm";
+import * as fitAdd from "@xterm/addon-fit";
+import { Fd, File, PreopenDirectory, WASI } from "@bjorn3/browser_wasi_shim";
+
+class XtermStdio extends Fd {
+ term: Terminal;
+
+ constructor(term: Terminal) {
+ super();
+ this.term = term;
+ }
+
+ fd_write(view8: Uint8Array, iovs: any) {
+ let nwritten = 0;
+ for (let iovec of iovs) {
+ console.log(
+ iovec.buf_len,
+ iovec.buf_len,
+ view8.slice(iovec.buf, iovec.buf + iovec.buf_len),
+ );
+ let buffer = view8.slice(iovec.buf, iovec.buf + iovec.buf_len);
+ this.term.write(buffer);
+ nwritten += iovec.buf_len;
+ }
+ return { ret: 0, nwritten };
+ }
+}
+
+const loadExternalFile = async (path: string) => {
+ return new File(await (await (await fetch(path)).blob()).arrayBuffer());
+};
+
+export interface WASITermProps {
+ href: string;
+ env: string[];
+ args: string[];
+}
+
+export default function WASITerm({ href, env, args }: WASITermProps) {
+ const root = <div style="max-width:80ch;max-height:20ch"></div>;
+
+ const term = new Terminal({
+ convertEol: true,
+ fontFamily: "Iosevka Curly Iaso",
+ });
+
+ const fit = new fitAdd.default();
+ term.loadAddon(fit);
+ fit.fit();
+
+ return (
+ <div>
+ {root}
+ <button
+ onClick={async () => {
+ term.writeln(`\x1B[93mfetching ${href}...\x1B[0m`);
+ const wasm = await WebAssembly.compileStreaming(fetch(href));
+ term.writeln("\x1B[93mdone, instantiating\x1B[0m");
+
+ const fds = [
+ new XtermStdio(term),
+ new XtermStdio(term),
+ new XtermStdio(term),
+ new PreopenDirectory("/tmp", {}),
+ ];
+
+ let wasi = new WASI(args, env, fds);
+ term.clear();
+ // let inst = await WebAssembly.instantiate(wasm, {
+ // "wasi_snapshot_preview1": wasi.wasiImport,
+ // });
+ // wasi.start(inst);
+ }}
+ >
+ Run
+ </button>
+ </div>
+ );
+}
diff --git a/src/frontend/deno.lock b/src/frontend/deno.lock
index 01f35a5..8c5f04b 100644
--- a/src/frontend/deno.lock
+++ b/src/frontend/deno.lock
@@ -1,9 +1,35 @@
{
"version": "2",
"remote": {
- "https://deno.land/x/wasm@v1.2.2/pkg/wasmer_wasi_js.d.ts": "0e202696f693f922ed63e1f372dd7b4641ce587d357fcf32de3d09cb48785867",
- "https://deno.land/x/wasm@v1.2.2/pkg/wasmer_wasi_js.js": "33c58765ded371211b754157955a7ab1d2de921a9c8fee8748112d25605726dd",
- "https://deno.land/x/wasm@v1.2.2/wasi.ts": "4fde34f8fa8c52af06adcc241f1b18fabf2df0d8b1f1b62d05e70377688a8fcb",
+ "https://deno.land/std@0.156.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74",
+ "https://deno.land/std@0.156.0/_util/os.ts": "3b4c6e27febd119d36a416d7a97bd3b0251b77c88942c8f16ee5953ea13e2e49",
+ "https://deno.land/std@0.156.0/path/_constants.ts": "df1db3ffa6dd6d1252cc9617e5d72165cd2483df90e93833e13580687b6083c3",
+ "https://deno.land/std@0.156.0/path/_interface.ts": "ee3b431a336b80cf445441109d089b70d87d5e248f4f90ff906820889ecf8d09",
+ "https://deno.land/std@0.156.0/path/_util.ts": "d16be2a16e1204b65f9d0dfc54a9bc472cafe5f4a190b3c8471ec2016ccd1677",
+ "https://deno.land/std@0.156.0/path/common.ts": "bee563630abd2d97f99d83c96c2fa0cca7cee103e8cb4e7699ec4d5db7bd2633",
+ "https://deno.land/std@0.156.0/path/glob.ts": "cb5255638de1048973c3e69e420c77dc04f75755524cb3b2e160fe9277d939ee",
+ "https://deno.land/std@0.156.0/path/mod.ts": "56fec03ad0ebd61b6ab39ddb9b0ddb4c4a5c9f2f4f632e09dd37ec9ebfd722ac",
+ "https://deno.land/std@0.156.0/path/posix.ts": "c1f7afe274290ea0b51da07ee205653b2964bd74909a82deb07b69a6cc383aaa",
+ "https://deno.land/std@0.156.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9",
+ "https://deno.land/std@0.156.0/path/win32.ts": "bd7549042e37879c68ff2f8576a25950abbfca1d696d41d82c7bca0b7e6f452c",
+ "https://deno.land/x/denoflate@1.2.1/mod.ts": "f5628e44b80b3d80ed525afa2ba0f12408e3849db817d47a883b801f9ce69dd6",
+ "https://deno.land/x/denoflate@1.2.1/pkg/denoflate.js": "b9f9ad9457d3f12f28b1fb35c555f57443427f74decb403113d67364e4f2caf4",
+ "https://deno.land/x/denoflate@1.2.1/pkg/denoflate_bg.wasm.js": "d581956245407a2115a3d7e8d85a9641c032940a8e810acbd59ca86afd34d44d",
+ "https://deno.land/x/esbuild@v0.15.10/mod.d.ts": "12e96a8d05c8e2c5638aa9cb09f24222134d437abb2f3f52de0156adb2270719",
+ "https://deno.land/x/esbuild@v0.15.10/mod.js": "b6076f05f58057025ce0eddb404a4da3b7a0e3768c53f6c87959c8c32240e9cd",
+ "https://deno.land/x/esbuild@v0.17.13/mod.d.ts": "dc279a3a46f084484453e617c0cabcd5b8bd1920c0e562e4ea02dfc828c8f968",
+ "https://deno.land/x/esbuild@v0.17.13/mod.js": "99302be2ce2a11eecd7a0764d970e2a0aa1c2d38d5ffcbb041d360a124c9aabc",
+ "https://deno.land/x/esbuild_deno_loader@0.6.0/deps.ts": "fe86f62cb954edc2580868cdc3292d4446f22cd2c4eedbf8ee26513fdf74e343",
+ "https://deno.land/x/esbuild_deno_loader@0.6.0/mod.ts": "5d8a429b26c70f9fd522a8629e751f3bdf63680da473e537bc420d552ee3bf0b",
+ "https://deno.land/x/esbuild_deno_loader@0.6.0/src/deno.ts": "0e83ccabbe2b004389288e38df2031b79eb347df2d139fce9394d8e88a11f259",
+ "https://deno.land/x/esbuild_deno_loader@0.6.0/src/native_loader.ts": "343854a566cf510cf25144f7c09fc0c1097780a31830305142a075d12bb697ba",
+ "https://deno.land/x/esbuild_deno_loader@0.6.0/src/portable_loader.ts": "35b6c526eed8c2c781a3256b23c30aa7cce69c0ef1d583c15528663287ba18a3",
+ "https://deno.land/x/esbuild_deno_loader@0.6.0/src/shared.ts": "b64749cd8c0f6252a11498bd8758ef1220003e46b2c9b68e16da63fd7e92b13a",
+ "https://deno.land/x/importmap@0.2.1/_util.ts": "ada9a9618b537e6c0316c048a898352396c882b9f2de38aba18fd3f2950ede89",
+ "https://deno.land/x/importmap@0.2.1/mod.ts": "ae3d1cd7eabd18c01a4960d57db471126b020f23b37ef14e1359bbb949227ade",
+ "https://esm.sh/v113/@bjorn3/browser_wasi_shim@0.2.7/es2022/browser_wasi_shim.mjs": "0d06fb9add2a2e53d8c52e3e5c3b5aa2115fe3ee651021d3ae1fff150a662e4e",
+ "https://esm.sh/v113/xterm-addon-fit@0.7.0/es2022/xterm-addon-fit.mjs": "131a41086e2e41272da58fac19e128029fb0d363103ae5f68bb71c8b7beadcf9",
+ "https://esm.sh/v113/xterm@5.1.0/es2022/xterm.mjs": "e0697e20cbe92d2177abe9fb744457df5c0f89f77a8e8ce7e9515b7d60f5cb57",
"https://xena.greedo.xeserv.us/pkg/xeact/v0.69.71/jsx-runtime.js": "a8e0e04c44bbc80bb0a8c59e1d3ee338dd799e25e89792cadb67f00bf4f6ceca",
"https://xena.greedo.xeserv.us/pkg/xeact/v0.69.71/xeact.js": "4b943b147cddd20b514b0cf85c68438e585712e809d8da4283ee5f0b8ac1ab8d",
"https://xena.greedo.xeserv.us/pkg/xeact/v0.69.71/xeact.ts": "b6def4bebff19548539f4708cff028cd1fd7abdf6bfd7b3cd8dd5025b97d676e"
diff --git a/src/frontend/deps.ts b/src/frontend/deps.ts
deleted file mode 100644
index f19e9ae..0000000
--- a/src/frontend/deps.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import * as wasi from "https://deno.land/x/wasm@v1.2.2/wasi.ts";
-//import * as xterm from "https://esm.sh/xterm@5.0.0?pin=v102";
-
-import * as xeact from "xeact";
-
-export {
- wasi,
- xeact,
- //xterm
-};
diff --git a/src/frontend/import_map.json b/src/frontend/import_map.json
index 9e87d14..5794405 100644
--- a/src/frontend/import_map.json
+++ b/src/frontend/import_map.json
@@ -1,8 +1,15 @@
{
"imports": {
+ "@bjorn3/browser_wasi_shim": "https://esm.sh/v113/@bjorn3/browser_wasi_shim@0.2.7/es2022/browser_wasi_shim.mjs",
+ "@xterm": "https://esm.sh/v113/xterm@5.1.0/es2022/xterm.mjs",
+ "@xterm/addon-fit": "https://esm.sh/v113/xterm-addon-fit@0.7.0/es2022/xterm-addon-fit.mjs",
+
+ "@esbuild": "https://deno.land/x/esbuild@v0.17.13/mod.js",
+ "@esbuild/deno": "https://deno.land/x/esbuild_deno_loader@0.6.0/mod.ts",
+
"xeact": "https://xena.greedo.xeserv.us/pkg/xeact/v0.69.71/xeact.ts",
"xeact/jsx-runtime": "https://xena.greedo.xeserv.us/pkg/xeact/v0.69.71/jsx-runtime.js",
- "/": "./",
+ "@/": "./",
"./": "./"
}
}
diff --git a/src/frontend/mastodon_share_button.tsx b/src/frontend/mastodon_share_button.tsx
deleted file mode 100644
index 744570f..0000000
--- a/src/frontend/mastodon_share_button.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-import { g, r, u, x } from "xeact";
-
-r(() => {
- const root = g("mastodon_share_button");
-
- let defaultURL = localStorage["mastodon_instance"];
-
- if (defaultURL == undefined) {
- defaultURL = "";
- }
-
- const title = document.querySelectorAll('meta[property="og:title"]')[0]
- .getAttribute("content");
- let series = g("mastodon_share_series").innerText;
- if (series != "") {
- series = `#${series} `;
- }
- const tags = g("mastodon_share_tags");
- const articleURL = u();
-
- const tootTemplate = `${title}
-
-${articleURL}
-
-${series}${tags.innerText} @cadey@pony.social`;
-
- const instanceBox = (
- <input type="text" placeholder="https://pony.social" value={defaultURL} />
- );
- const tootBox = <textarea rows={6} cols={40}>{tootTemplate}</textarea>;
-
- const doShare = () => {
- let instanceURL = instanceBox.value;
-
- if (!instanceURL.startsWith("https://")) {
- instanceURL = `https://${instanceURL}`;
- }
-
- localStorage["mastodon_instance"] = instanceURL;
- const text = tootBox.value;
- const mastodonURL = u(instanceURL + "/share", { text, visibility: "public" });
- console.log({ text, mastodonURL });
- window.open(mastodonURL, "_blank");
- };
-
- const shareButton = <button onclick={doShare}>Share</button>;
-
- x(root);
-
- root.appendChild(
- <div>
- <details>
- <summary>Share on Mastodon</summary>
- <span>Instance URL (https://mastodon.example)</span>
- <br />
- {instanceBox}
- <br />
- {tootBox}
- <br />
- {shareButton}
- </details>
- </div>,
- );
-});
diff --git a/src/frontend/state.js b/src/frontend/state.js
new file mode 100644
index 0000000..195fd24
--- /dev/null
+++ b/src/frontend/state.js
@@ -0,0 +1,5 @@
+export const useState = (value = undefined) => {
+ return [() => value, (x) => {
+ value = x;
+ }];
+};
diff --git a/src/frontend/wasiterm.tsx b/src/frontend/wasiterm.tsx
deleted file mode 100644
index a9b0ea5..0000000
--- a/src/frontend/wasiterm.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import { wasi as wasiMod, xeact, /*xterm*/ } from "./deps.ts";
-
-const { x, t } = xeact;
-//const { Terminal } = xterm;
-const { WASI } = wasiMod;
-
-const init = async (rootElem: Element, wasmURL: string) => {
- //const termElem = <div></div>;
- const termElem = <code></code>;
-
- //const term = new Terminal();
- //term.open(termElem);
-
- const runProgram = async () => {
- await wasiMod.init(new URL("https://cdn.xeiaso.net/file/christine-static/wasm/5410143de81b20061e9750d1cf80aceef56d2938ab949e30dd7b13fa699307ad.wasm"));
-
- //term.writeln(`loading ${wasmURL}`);
- termElem.appendChild(t(`loading ${wasmURL}`));
-
- const wasi = new WASI({
- env: {
- "HOSTNAME": "pyra",
- },
- })
-
- const moduleBytes = fetch(wasmURL);
- const module = await WebAssembly.compileStreaming(moduleBytes);
- await wasi.instantiate(module, {});
- //term.writeln("executing");
- termElem.appendChild(t("executing"));
- let exitCode = wasi.start();
- let stdout = wasi.getStdoutString();
- console.log(`${stdout}\n\n(exit code: ${exitCode})`);
- //term.writeln(`${stdout}\n\n(exit code: ${exitCode})`);
- termElem.appendChild(t(`${stdout}\n\n(exit code: ${exitCode})`));
- };
-
- const runButton = <button onclick={runProgram}>Run</button>;
-
- const root = <div>
- <link rel="stylesheet" href="https://cdn.xeiaso.net/file/christine-static/wasm/xterm/xterm-a36f07105014cc9220cae423d97c30d1a59fdb0230da8e53bb74bb0faade4310.css" type="text/css" />
- {runButton}
- <pre>{termElem}</pre>
- </div>;
-
- x(rootElem);
- rootElem.appendChild(root);
-
- //term.writeln(`loading ${wasmURL}`);
- //term.writeln(`${stdout}\n\n(exit code: ${exitCode})`);
-}
-
-export { init };
diff --git a/src/tmpl/blog.rs b/src/tmpl/blog.rs
index f940db4..18d66e7 100644
--- a/src/tmpl/blog.rs
+++ b/src/tmpl/blog.rs
@@ -1,6 +1,7 @@
use super::{base, nag};
use crate::post::{schemaorg::Article, Post};
use maud::{html, Markup, PreEscaped};
+use xesite_templates::xeact_component;
fn post_metadata(post: &Post) -> Markup {
let art: Article = post.into();
@@ -28,11 +29,19 @@ fn post_metadata(post: &Post) -> Markup {
}
fn share_button(post: &Post) -> Markup {
+ return xeact_component("MastodonShareButton", serde_json::json!({
+ "title": post.front_matter.title,
+ "series": post.front_matter.series,
+ "tags": post.front_matter.tags.as_ref().unwrap_or(&Vec::new())
+ }));
+}
+
+fn share_button_old(post: &Post) -> Markup {
html! {
div # mastodon_share_button {}
div # mastodon_share_series style="display:none" {(post.front_matter.series.as_ref().unwrap_or(&"".to_string()))}
div # mastodon_share_tags style="display:none" {@for tag in post.front_matter.tags.as_ref().unwrap_or(&Vec::new()) {"#" (tag) " "}}
- script r#type="module" src="/static/js/mastodon_share_button.js" {}
+ script type="module" src="/static/js/mastodon_share_button.js" {}
}
}
diff --git a/static/wasm/.gitignore b/static/wasm/.gitignore
new file mode 100644
index 0000000..19e1bce
--- /dev/null
+++ b/static/wasm/.gitignore
@@ -0,0 +1 @@
+*.wasm
diff --git a/static/xeact/.gitignore b/static/xeact/.gitignore
new file mode 100644
index 0000000..a6c7c28
--- /dev/null
+++ b/static/xeact/.gitignore
@@ -0,0 +1 @@
+*.js
diff --git a/wasi/.gitignore b/wasi/.gitignore
new file mode 100644
index 0000000..4c82b07
--- /dev/null
+++ b/wasi/.gitignore
@@ -0,0 +1,2 @@
+zig-cache
+zig-out
diff --git a/wasi/build.zig b/wasi/build.zig
new file mode 100644
index 0000000..23c210f
--- /dev/null
+++ b/wasi/build.zig
@@ -0,0 +1,15 @@
+const std = @import("std");
+const Builder = std.build.Builder;
+const CrossTarget = std.zig.CrossTarget;
+
+pub fn build(b: *std.build.Builder) void {
+ // Standard release options allow the person running `zig build` to select
+ // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
+ const mode = b.standardReleaseOptions();
+ const target = CrossTarget{ .cpu_arch = .wasm32, .os_tag = .wasi };
+
+ const exe = b.addExecutable("hello", "src/hello.zig");
+ exe.setTarget(target);
+ exe.setBuildMode(mode);
+ exe.install();
+}
diff --git a/wasi/src/hello.zig b/wasi/src/hello.zig
new file mode 100644
index 0000000..a1937b8
--- /dev/null
+++ b/wasi/src/hello.zig
@@ -0,0 +1,5 @@
+const std = @import("std");
+
+pub fn main() !void {
+ try std.io.getStdOut().writeAll("Hello World!");
+}