Files
zeekay d7441eaf29 zapweb/ts: faithful binary ZAP codec + browser client (@zap-proto/web)
The browser half of one protocol. A TypeScript port of the ZAP wire
codec (zap.go + builder.go) byte-identical to Go — proven by golden
vectors emitted from golden_test.go (12/12 encode+decode) — plus a
zapweb WebSocket client mirroring client.go (opcode stamp, [reqID][flag]
correlation), validated by a live TS-client to Go-echoserver round-trip
(cmd/echoserver). procedureOpcode matches Go FNV-1a. Zero runtime deps:
browser-global WebSocket, Node native type-stripping for tests.
2026-06-15 13:32:13 -07:00

52 lines
1.4 KiB
Go

// Command echoserver runs a zapweb (ZAP-over-WebSocket) echo service for
// cross-language integration testing. It registers test.echo (prefixes
// its text@0 argument with "echo:") and serves it at /zap, so the
// TypeScript client in zapweb/ts can prove the browser path is wire-
// compatible end to end.
//
// go run ./zapweb/cmd/echoserver # serves :8089/zap
package main
import (
"context"
"log"
"net/http"
"os"
zap "github.com/luxfi/zap"
"github.com/luxfi/zap/zapclient"
"github.com/luxfi/zap/zapweb"
)
func main() {
addr := ":8089"
if v := os.Getenv("ECHO_ADDR"); v != "" {
addr = v
}
srv, err := zapclient.NewServer("_lux-echo._tcp",
zapclient.WithNoDiscovery(),
zapclient.WithServerPort(0),
)
if err != nil {
log.Fatalf("echoserver: %v", err)
}
if err := srv.Register("test.echo", func(ctx context.Context, peer zapclient.PeerInfo, req *zap.Message) (*zap.Message, error) {
in := req.Root().Text(0)
b := zap.NewBuilder(256)
ob := b.StartObject(64)
ob.SetText(0, "echo:"+in)
ob.FinishAsRoot()
out, _ := zap.Parse(b.Finish())
return out, nil
}); err != nil {
log.Fatalf("echoserver register: %v", err)
}
mux := http.NewServeMux()
mux.Handle("/zap", zapweb.Handler(srv, zapweb.Options{OriginPatterns: []string{"*"}}))
log.Printf("zapweb echo serving %s/zap", addr)
if err := http.ListenAndServe(addr, mux); err != nil {
log.Fatalf("echoserver listen: %v", err)
}
}