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>
106 lines
2.3 KiB
Go
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
|
|
}
|