All of the components are not that great for their original purpose. But in combination they work well as an adjustable desk lamp for different moods.
Die Weihnachtsgeschenke sind ausgepackt, hier die Auflösung, was ich auf das Leder graviert hab: Hnefatafl. Ein Wikingerspiel mit massiv asymmetrischer Spielweise. Die Spielsteine sind koreanische Go-Linsen mit 20.5mm Durchmesser. Jedes Quadrat ist 25mm groß, das gesamte Grid also 275mm x 275mm. Der Umkreis hat einen Durchmesser von 400mm. Es werden 24 schwarze Steine und 12+1 weiße benötigt. Die Parameter zur Gravur findet ihr im vorherigen Post. Enjoy.
with TypeScript frontend, REST, a .txt as “data store”, no external dependencies, all compiling to a single binary. The overwhelming result:
But it represents a starting point for a three tier application. Any real world example would use an actual database and maybe a better routing scheme. You need Go, tsc
(npm install -g typescript
), Make
and a browser. Compile and start with make
, then open http://localhost:8000 and hit the button.
$ cat Makefile
all: hello.js hello
hello.js: hello.ts
which tsc || sudo npm install -g typescript
tsc hello.ts
hello:
go run hello.go
$ cat hello.ts
interface Answer {
Current: Number
}
async function getCurrent() {
let answer = await fetch("/current")
.then(res => res.json())
.then(res => res as Answer);
let counter = document.getElementById('current');
if (counter != null)
counter.innerText = answer.Current.toString();
}
$ cat go.mod
module hello
go 1.16
$ cat hello.go
package main
import (
_ "embed"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
//go:embed hello.js
var js string
var html string = `
<html>
<head><title></title>
<script>` + js + `
</script>
</head>
<body>
<h1 id="current"></h1>
<button onclick="getCurrent()">Load Current</button>
</body>
</html>
`
const storefile = "myfancydatastore.txt"
type Answer struct {
Current int
}
func readFromStore() Answer {
b, err := ioutil.ReadFile(storefile)
if err != nil {
// do something
}
var a Answer
err = json.Unmarshal(b, &a)
if err != nil {
// do something
}
return a
}
func writeToStore(a Answer) {
b, err := json.Marshal(a)
if err != nil {
// do something
}
ioutil.WriteFile(storefile, b, 0644)
}
func serveIndex(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet {
w.Header().Set("content-type", "text/html; charset=utf-8")
w.Write([]byte(html))
}
}
func handler(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet {
w.Header().Set("content-type", "application/json")
a := readFromStore()
b, err := json.Marshal(a)
if err != nil {
// do something
}
w.Write(b)
a.Current = a.Current + 1
writeToStore(a)
}
}
func main() {
writeToStore(Answer{Current: 0})
mux := http.NewServeMux()
mux.HandleFunc("/", serveIndex)
mux.HandleFunc("/current", handler)
fmt.Println("Starting server on localhost:8000")
http.ListenAndServe("localhost:8000", mux)
}
I pushed hedgedoc-watcher to git.fireandbrimst.one, which allows watching hedgedoc notes with an RSS reader.