Files
yawn/server/main.go
T
Ampandheaust 7070799862 Add Go CDN and playground server
Build Core and Handles into in-memory CDN modules, add the marketing site and tutorial docs, and provide a SQLite-backed WebGPU playground with TypeScript tooling and profiling.

Amp-Thread-ID: https://ampcode.com/threads/T-01a02485-5574-707c-bff4-5668d83bee8a
Co-authored-by: Heaust Azure <heaust.azure@gmail.com>
2026-08-21 16:42:02 +00:00

109 lines
2.3 KiB
Go

package main
import (
"context"
"errors"
"fmt"
"log"
"net/http"
"os"
"os/signal"
"path/filepath"
"syscall"
"time"
)
func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}
func run() error {
root, err := repositoryRoot()
if err != nil {
return err
}
log.Print("building core and handles packages")
packages, err := buildPackages(root)
if err != nil {
return fmt.Errorf("build packages: %w", err)
}
log.Printf("loaded %d package assets into memory", len(packages))
databasePath := os.Getenv("YAWN_DATABASE")
if databasePath == "" {
databasePath = filepath.Join(root, "server", "data", "yawn.db")
}
store, err := openPlaygroundStore(databasePath)
if err != nil {
return fmt.Errorf("open playground database: %w", err)
}
defer store.Close()
app, err := newApplication(
store,
packages,
filepath.Join(root, "node_modules", "monaco-editor", "min"),
)
if err != nil {
return err
}
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
server := &http.Server{
Addr: ":" + port,
Handler: app.routes(),
ReadHeaderTimeout: 5 * time.Second,
ReadTimeout: 15 * time.Second,
WriteTimeout: 30 * time.Second,
IdleTimeout: 60 * time.Second,
}
stopped := make(chan os.Signal, 1)
signal.Notify(stopped, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-stopped
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
log.Printf("shutdown: %v", err)
}
}()
log.Printf("Yawn server listening on http://0.0.0.0:%s", port)
err = server.ListenAndServe()
if errors.Is(err, http.ErrServerClosed) {
return nil
}
return err
}
func repositoryRoot() (string, error) {
directory, err := os.Getwd()
if err != nil {
return "", err
}
for {
if fileExists(filepath.Join(directory, "Cargo.toml")) &&
fileExists(filepath.Join(directory, "core", "Cargo.toml")) &&
fileExists(filepath.Join(directory, "addons", "handles", "package.json")) {
return directory, nil
}
parent := filepath.Dir(directory)
if parent == directory {
return "", errors.New("could not find the Yawn repository root")
}
directory = parent
}
}
func fileExists(path string) bool {
info, err := os.Stat(path)
return err == nil && !info.IsDir()
}