Files
yawn/server/packages.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

106 lines
2.3 KiB
Go

package main
import (
"bytes"
"crypto/sha256"
"fmt"
"io/fs"
"mime"
"os"
"os/exec"
"path/filepath"
"time"
)
type memoryAsset struct {
contentType string
content []byte
etag string
modified time.Time
}
func buildPackages(root string) (map[string]memoryAsset, error) {
output, err := os.MkdirTemp("", "yawn-packages-*")
if err != nil {
return nil, err
}
defer os.RemoveAll(output)
if err := runBuild(root, "wasm-pack", "build", filepath.Join(root, "core"),
"--target", "web", "--out-dir", filepath.Join(output, "pkg"), "--release"); err != nil {
return nil, err
}
if err := runBuild(root, "node", filepath.Join(root, "server", "build.mjs"), root, output); err != nil {
return nil, err
}
assets := make(map[string]memoryAsset)
for _, name := range []string{
"core.js",
"handles.js",
"worker.js",
"importer-worker.js",
"bvh-worker.js",
} {
asset, err := loadMemoryAsset(filepath.Join(output, name))
if err != nil {
return nil, err
}
assets[name] = asset
}
err = filepath.WalkDir(filepath.Join(output, "pkg"), func(path string, entry fs.DirEntry, walkErr error) error {
if walkErr != nil {
return walkErr
}
if entry.IsDir() {
return nil
}
relative, err := filepath.Rel(filepath.Join(output, "pkg"), path)
if err != nil {
return err
}
asset, err := loadMemoryAsset(path)
if err != nil {
return err
}
assets[filepath.ToSlash(filepath.Join("pkg", relative))] = asset
return nil
})
if err != nil {
return nil, err
}
return assets, nil
}
func runBuild(directory, name string, arguments ...string) error {
command := exec.Command(name, arguments...)
command.Dir = directory
command.Env = os.Environ()
var output bytes.Buffer
command.Stdout = &output
command.Stderr = &output
if err := command.Run(); err != nil {
return fmt.Errorf("%s: %w\n%s", name, err, output.String())
}
return nil
}
func loadMemoryAsset(path string) (memoryAsset, error) {
content, err := os.ReadFile(path)
if err != nil {
return memoryAsset{}, err
}
digest := sha256.Sum256(content)
contentType := mime.TypeByExtension(filepath.Ext(path))
if contentType == "" {
contentType = "application/octet-stream"
}
return memoryAsset{
contentType: contentType,
content: content,
etag: fmt.Sprintf("\"%x\"", digest[:12]),
modified: time.Now().UTC(),
}, nil
}