Skip to content

Instantly share code, notes, and snippets.

@whiteinge
Created February 25, 2025 00:59
Show Gist options
  • Save whiteinge/9ff409080174c0e7dd8f4239876beecb to your computer and use it in GitHub Desktop.
Save whiteinge/9ff409080174c0e7dd8f4239876beecb to your computer and use it in GitHub Desktop.
Datastar proof-of-concept with POSIX sh and socat
#!/usr/bin/env sh
# Datastar POC in a bottle via POSIX sh and socat
_html() {
printf 'HTTP/1.0 200\r
Content-Type: text/html\r
\r
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Datastar Test</title>
<script type="module" src="https://cdn.jsdelivr.net/gh/starfederation/[email protected]/bundles/datastar.js"></script>
</head>
<body data-on-load="@get('\''/datastar/'\'')" id="body">
<h1>Hello, world.</h1>
<div id="date"></div>
<div id="count"></div>
</body>
</html>
'
}
_datastar() {
printf 'HTTP/1.0 200\r
Content-Type: text/event-stream\r
Cache-Control: no-cache\r
\r'
count=0
while true; do
ps -p "$SOCAT_PID" 1>/dev/null 2>/dev/null
if [ $? -ne 0 ]; then break; fi
printf 'event: datastar-merge-fragments\n'
printf 'data: fragments <div id="date">%s</div>\n' \
"$(date --iso-8601=seconds -u)"
printf 'data: fragments <div id="count">%s</div>\n\n' "$count"
count=$(( count + 1 ))
sleep 0.1
done
}
_main() {
# Preamble
read -r HTTP_METHOD HTTP_RELREF HTTP_VERSION
HTTP_PATH="${HTTP_RELREF%\?*}"
HTTP_QUERY="${HTTP_RELREF#\?*}"
# Headers
crlf=$(printf '\r\n')
clen=0
while read -r hdr; do
[ "$hdr" = "$crlf" ] && break
t=$(printf '%s\n' "$hdr" | sed -n '/^content-length/s/.*: //p')
[ -n "$t" ] && clen=$t
done
case "$HTTP_PATH" in
'/') cmd=_html;;
/datastar*) cmd=_datastar;;
esac
# Body
dd bs=1 count="$clen" 2>/dev/null | "$cmd" "$HTTP_PATH" "$HTTP_QUERY"
}
if [ $# -eq 0 ]; then
socat "TCP-LISTEN:8000,fork,reuseaddr" EXEC:"${0} _main"
else
cmd="$1"
shift 1
"$cmd" "$@"
fi
@whiteinge
Copy link
Author

whiteinge commented Feb 25, 2025

Run the script, then navigate to http://localhost:8000/ in a browser.

Visit https://data-star.dev/ to see where the magic comes from.

@Superpat
Copy link

This is really cool. Reminds me of my eurobsdcon presentation (http://www.patrickmarchand.com:8083/openbsd-datastar/intro.html), where the datastar examples are c programs and ksh scripts (runned via cgi)

@pholly
Copy link

pholly commented Feb 25, 2025

Wow really cool! I didn't know a bash script could serve up a web server

@whiteinge
Copy link
Author

@Superpat nice presentation! That interactivity is a lot of fun. Plus ksh and cgi always get bonus points.

@whiteinge
Copy link
Author

whiteinge commented Feb 25, 2025

@pholly I don't have enough good things to say about socat. Whether or not request/response parsing in shell is a good idea is another question 😜 . However it is fun...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment