From 75b9e83039705fd43187ea78b2a38b695ca65596 Mon Sep 17 00:00:00 2001 From: Adnaan Date: Wed, 12 Nov 2025 08:19:48 +0100 Subject: [PATCH 1/5] refactor: update to use Must(New()) pattern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update all livetemplate.New() calls to use Must(New()) pattern to work with the new API that returns (*Template, error). Changes: - All main.go files now use livetemplate.Must(livetemplate.New(...)) - Compatible with livetemplate v0.3.0+ API changes - Maintains fail-fast behavior for template initialization errors Updated files: - chat/main.go - counter/main.go - graceful-shutdown/main.go - observability/main.go - production/single-host/main.go - testing/01_basic/main.go - todos/main.go - trace-correlation/main.go - avatar-upload/ (new example) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- avatar-upload/README.md | 166 ++++++++++++++++ avatar-upload/avatar-upload.tmpl | 317 +++++++++++++++++++++++++++++++ avatar-upload/go.mod | 45 +++++ avatar-upload/go.sum | 180 ++++++++++++++++++ avatar-upload/main.go | 133 +++++++++++++ avatar-upload/run.sh | 11 ++ chat/main.go | 2 +- counter/go.mod | 3 + counter/go.sum | 4 +- counter/main.go | 2 +- graceful-shutdown/main.go | 2 +- observability/main.go | 2 +- production/single-host/main.go | 2 +- testing/01_basic/main.go | 2 +- todos/main.go | 2 +- trace-correlation/main.go | 2 +- 16 files changed, 865 insertions(+), 10 deletions(-) create mode 100644 avatar-upload/README.md create mode 100644 avatar-upload/avatar-upload.tmpl create mode 100644 avatar-upload/go.mod create mode 100644 avatar-upload/go.sum create mode 100644 avatar-upload/main.go create mode 100755 avatar-upload/run.sh diff --git a/avatar-upload/README.md b/avatar-upload/README.md new file mode 100644 index 0000000..8a082e0 --- /dev/null +++ b/avatar-upload/README.md @@ -0,0 +1,166 @@ +# Avatar Upload Example + +A simple example demonstrating LiveTemplate's file upload feature with avatar upload functionality. + +## Features + +- 📸 **Image Upload**: Upload JPEG, PNG, or GIF avatars +- 📊 **Real-time Progress**: WebSocket chunked upload with live progress tracking +- ✅ **Validation**: Automatic file type and size validation (5MB limit) +- 🎨 **Beautiful UI**: Gradient design with smooth animations +- 🔄 **Live Updates**: Profile updates instantly without page reload + +## What This Example Demonstrates + +### Upload Configuration +```go +func (s *ProfileStore) AllowUploads() map[string]livetemplate.UploadConfig { + return map[string]livetemplate.UploadConfig{ + "avatar": { + Accept: []string{"image/jpeg", "image/png", "image/gif"}, + MaxFileSize: 5 * 1024 * 1024, // 5MB + MaxEntries: 1, // Single file + AutoUpload: false, // Manual upload on form submit + ChunkSize: 256 * 1024, // 256KB chunks + }, + } +} +``` + +### Upload Processing +```go +func (s *ProfileStore) ConsumeUpload(ctx context.Context, name string, entries []*livetemplate.UploadEntry) error { + for _, entry := range entries { + // Move from temp to permanent location + permanentPath := filepath.Join("uploads", fmt.Sprintf("avatar-%s%s", entry.ID, ext)) + os.Rename(entry.TempPath, permanentPath) + + // Update store with new avatar + s.AvatarPath = permanentPath + s.AvatarURL = "/" + permanentPath + } + return nil +} +``` + +### Template Helpers +```html + + + +{{range .lvt.Uploads "avatar"}} +
+ {{.ClientName}} - {{.Progress}}% + + {{if .Error}}{{.Error}}{{end}} +
+{{end}} +``` + +## Running the Example + +### 1. Install Dependencies + +```bash +cd /Users/adnaan/code/livetemplate/examples/avatar-upload +go mod download +``` + +### 2. Run the Server + +```bash +go run main.go +``` + +The server will start at http://localhost:8080 + +### 3. Try It Out + +1. Open http://localhost:8080 in your browser +2. Click "Choose File" and select an image (JPEG, PNG, or GIF) +3. Click "Save Profile" +4. Watch the real-time progress bar as your file uploads +5. See your avatar appear instantly when upload completes! + +## Upload Strategies + +This example uses **WebSocket Chunked Upload**: +- ✅ Real-time progress tracking +- ✅ Handles large files efficiently (256KB chunks) +- ✅ Non-blocking uploads +- ✅ Works with LiveTemplate's reactive updates + +## File Structure + +``` +avatar-upload/ +├── main.go # Server code with ProfileStore +├── avatar-upload.tmpl # HTML template with upload UI +├── go.mod # Dependencies (uses local livetemplate) +├── README.md # This file +└── uploads/ # Created at runtime for uploaded avatars +``` + +## Testing Different Scenarios + +### Valid Upload +- Upload a JPEG, PNG, or GIF under 5MB +- ✅ Should show progress and complete successfully + +### File Too Large +- Upload an image over 5MB +- ❌ Should show validation error + +### Invalid File Type +- Upload a non-image file (e.g., .txt, .pdf) +- ❌ Should show "file type not accepted" error + +### Multiple Files +- Try selecting multiple images +- â„šī¸ Only the first will be accepted (MaxEntries: 1) + +## Code Quality + +This example demonstrates: +- ✅ Clean separation of concerns (Store pattern) +- ✅ Proper error handling +- ✅ File validation and security +- ✅ Temp file cleanup +- ✅ LiveTemplate best practices + +## Next Steps + +Want to extend this example? + +1. **Add S3 Upload**: Replace local storage with S3 presigner +2. **Multiple Avatars**: Change `MaxEntries` to allow multiple images +3. **Image Cropping**: Add client-side cropping before upload +4. **Drag & Drop**: Add drag-and-drop file selection +5. **Auto-Upload**: Set `AutoUpload: true` for instant uploads + +## Learn More + +- [Upload Documentation](../../livetemplate/.worktrees/feature-uploads/docs/uploads.md) +- [LiveTemplate Documentation](https://github.com/livetemplate/livetemplate) +- [Other Examples](../) + +## Troubleshooting + +**Upload not working?** +- Check browser console for errors +- Ensure WebSocket connection is established (look for green indicator) +- Verify file meets validation criteria (type, size) + +**Progress not updating?** +- Make sure you're using WebSocket (not HTTP fallback) +- Check that ChunkSize is set appropriately +- Verify client library is loaded + +**Files not saving?** +- Check that `uploads/` directory exists (created automatically) +- Verify file permissions on the uploads directory +- Check server logs for errors + +--- + +Built with â¤ī¸ using [LiveTemplate v0.3.0](https://github.com/livetemplate/livetemplate) diff --git a/avatar-upload/avatar-upload.tmpl b/avatar-upload/avatar-upload.tmpl new file mode 100644 index 0000000..30a7983 --- /dev/null +++ b/avatar-upload/avatar-upload.tmpl @@ -0,0 +1,317 @@ + + + + + + Avatar Upload Example - LiveTemplate + + + +
+

Profile Settings

+

Upload your avatar and update your profile

+ +
+ 📸 Accepted: JPEG, PNG, GIF â€ĸ Max size: 5MB â€ĸ WebSocket chunked upload with real-time progress +
+ +
+
+ {{if .AvatarURL}} + Avatar + {{else}} + {{slice .Name 0 1}} + {{end}} +
+
+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ {{range .lvt.Uploads "avatar"}} +
+
+ {{.ClientName}} + {{.Progress}}% +
+
+
+
+ {{if .Error}} +
❌ {{.Error}}
+ {{else if .Done}} +
✅ Upload complete!
+ {{end}} +
+ {{end}} + + {{if .lvt.HasUploadError "avatar"}} +
âš ī¸ {{.lvt.UploadError "avatar"}}
+ {{end}} +
+ + +
+ +
+ Powered by LiveTemplate v0.3.0 +
+
+ + + + + diff --git a/avatar-upload/go.mod b/avatar-upload/go.mod new file mode 100644 index 0000000..1b390c9 --- /dev/null +++ b/avatar-upload/go.mod @@ -0,0 +1,45 @@ +module github.com/livetemplate/examples/avatar-upload + +go 1.25.3 + +require github.com/livetemplate/livetemplate v0.3.0 + +require ( + github.com/aws/aws-sdk-go-v2 v1.39.6 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.3 // indirect + github.com/aws/aws-sdk-go-v2/config v1.31.17 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.18.21 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.13 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.13 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.13 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.13 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.13 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.13 // indirect + github.com/aws/aws-sdk-go-v2/service/s3 v1.90.0 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.30.1 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.39.1 // indirect + github.com/aws/smithy-go v1.23.2 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/gabriel-vasile/mimetype v1.4.10 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.28.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/websocket v1.5.3 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/redis/go-redis/v9 v9.16.0 // indirect + github.com/tdewolff/minify/v2 v2.24.3 // indirect + github.com/tdewolff/parse/v2 v2.8.3 // indirect + golang.org/x/crypto v0.42.0 // indirect + golang.org/x/net v0.44.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.14.0 // indirect +) + +replace github.com/livetemplate/livetemplate => ../../livetemplate/.worktrees/feature-uploads diff --git a/avatar-upload/go.sum b/avatar-upload/go.sum new file mode 100644 index 0000000..de73ae4 --- /dev/null +++ b/avatar-upload/go.sum @@ -0,0 +1,180 @@ +dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= +dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/aws/aws-sdk-go-v2 v1.39.6 h1:2JrPCVgWJm7bm83BDwY5z8ietmeJUbh3O2ACnn+Xsqk= +github.com/aws/aws-sdk-go-v2 v1.39.6/go.mod h1:c9pm7VwuW0UPxAEYGyTmyurVcNrbF6Rt/wixFqDhcjE= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.3 h1:DHctwEM8P8iTXFxC/QK0MRjwEpWQeM9yzidCRjldUz0= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.3/go.mod h1:xdCzcZEtnSTKVDOmUZs4l/j3pSV6rpo1WXl5ugNsL8Y= +github.com/aws/aws-sdk-go-v2/config v1.31.17 h1:QFl8lL6RgakNK86vusim14P2k8BFSxjvUkcWLDjgz9Y= +github.com/aws/aws-sdk-go-v2/config v1.31.17/go.mod h1:V8P7ILjp/Uef/aX8TjGk6OHZN6IKPM5YW6S78QnRD5c= +github.com/aws/aws-sdk-go-v2/credentials v1.18.21 h1:56HGpsgnmD+2/KpG0ikvvR8+3v3COCwaF4r+oWwOeNA= +github.com/aws/aws-sdk-go-v2/credentials v1.18.21/go.mod h1:3YELwedmQbw7cXNaII2Wywd+YY58AmLPwX4LzARgmmA= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.13 h1:T1brd5dR3/fzNFAQch/iBKeX07/ffu/cLu+q+RuzEWk= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.13/go.mod h1:Peg/GBAQ6JDt+RoBf4meB1wylmAipb7Kg2ZFakZTlwk= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.13 h1:a+8/MLcWlIxo1lF9xaGt3J/u3yOZx+CdSveSNwjhD40= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.13/go.mod h1:oGnKwIYZ4XttyU2JWxFrwvhF6YKiK/9/wmE3v3Iu9K8= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.13 h1:HBSI2kDkMdWz4ZM7FjwE7e/pWDEZ+nR95x8Ztet1ooY= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.13/go.mod h1:YE94ZoDArI7awZqJzBAZ3PDD2zSfuP7w6P2knOzIn8M= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.13 h1:eg/WYAa12vqTphzIdWMzqYRVKKnCboVPRlvaybNCqPA= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.13/go.mod h1:/FDdxWhz1486obGrKKC1HONd7krpk38LBt+dutLcN9k= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3 h1:x2Ibm/Af8Fi+BH+Hsn9TXGdT+hKbDd5XOTZxTMxDk7o= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3/go.mod h1:IW1jwyrQgMdhisceG8fQLmQIydcT/jWY21rFhzgaKwo= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.4 h1:NvMjwvv8hpGUILarKw7Z4Q0w1H9anXKsesMxtw++MA4= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.4/go.mod h1:455WPHSwaGj2waRSpQp7TsnpOnBfw8iDfPfbwl7KPJE= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.13 h1:kDqdFvMY4AtKoACfzIGD8A0+hbT41KTKF//gq7jITfM= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.13/go.mod h1:lmKuogqSU3HzQCwZ9ZtcqOc5XGMqtDK7OIc2+DxiUEg= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.13 h1:zhBJXdhWIFZ1acfDYIhu4+LCzdUS2Vbcum7D01dXlHQ= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.13/go.mod h1:JaaOeCE368qn2Hzi3sEzY6FgAZVCIYcC2nwbro2QCh8= +github.com/aws/aws-sdk-go-v2/service/s3 v1.90.0 h1:ef6gIJR+xv/JQWwpa5FYirzoQctfSJm7tuDe3SZsUf8= +github.com/aws/aws-sdk-go-v2/service/s3 v1.90.0/go.mod h1:+wArOOrcHUevqdto9k1tKOF5++YTe9JEcPSc9Tx2ZSw= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.1 h1:0JPwLz1J+5lEOfy/g0SURC9cxhbQ1lIMHMa+AHZSzz0= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.1/go.mod h1:fKvyjJcz63iL/ftA6RaM8sRCtN4r4zl4tjL3qw5ec7k= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.5 h1:OWs0/j2UYR5LOGi88sD5/lhN6TDLG6SfA7CqsQO9zF0= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.5/go.mod h1:klO+ejMvYsB4QATfEOIXk8WAEwN4N0aBfJpvC+5SZBo= +github.com/aws/aws-sdk-go-v2/service/sts v1.39.1 h1:mLlUgHn02ue8whiR4BmxxGJLR2gwU6s6ZzJ5wDamBUs= +github.com/aws/aws-sdk-go-v2/service/sts v1.39.1/go.mod h1:E19xDjpzPZC7LS2knI9E6BaRFDK43Eul7vd6rSq2HWk= +github.com/aws/smithy-go v1.23.2 h1:Crv0eatJUQhaManss33hS5r40CG3ZFH+21XSkqMrIUM= +github.com/aws/smithy-go v1.23.2/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= +github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= +github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= +github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= +github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= +github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= +github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= +github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= +github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= +github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA= +github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/docker/docker v28.3.3+incompatible h1:Dypm25kh4rmk49v1eiVbsAtpAsYURjYkaKubwuBdxEI= +github.com/docker/docker v28.3.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94= +github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw= +github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/gabriel-vasile/mimetype v1.4.10 h1:zyueNbySn/z8mJZHLt6IPw0KoZsiQNszIpU+bX4+ZK0= +github.com/gabriel-vasile/mimetype v1.4.10/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.28.0 h1:Q7ibns33JjyW48gHkuFT91qX48KG0ktULL6FgHdG688= +github.com/go-playground/validator/v10 v10.28.0/go.mod h1:GoI6I1SjPBh9p7ykNE/yj3fFYbyDOpwMn5KXd+m2hUU= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE= +github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mdelapenya/tlscert v0.2.0 h1:7H81W6Z/4weDvZBNOfQte5GpIMo0lGYEeWbkGp5LJHI= +github.com/mdelapenya/tlscert v0.2.0/go.mod h1:O4njj3ELLnJjGdkN7M/vIVCpZ+Cf0L6muqOG4tLSl8o= +github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= +github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= +github.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ= +github.com/moby/go-archive v0.1.0/go.mod h1:G9B+YoujNohJmrIYFBpSd54GTUB4lt9S+xVQvsJyFuo= +github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= +github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= +github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= +github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko= +github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs= +github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= +github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= +github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= +github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/redis/go-redis/v9 v9.16.0 h1:OotgqgLSRCmzfqChbQyG1PHC3tLNR89DG4jdOERSEP4= +github.com/redis/go-redis/v9 v9.16.0/go.mod h1:u410H11HMLoB+TP67dz8rL9s6QW2j76l0//kSOd3370= +github.com/shirou/gopsutil/v4 v4.25.6 h1:kLysI2JsKorfaFPcYmcJqbzROzsBWEOAtw6A7dIfqXs= +github.com/shirou/gopsutil/v4 v4.25.6/go.mod h1:PfybzyydfZcN+JMMjkF6Zb8Mq1A/VcogFFg7hj50W9c= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/stretchr/testify v1.11.0 h1:ib4sjIrwZKxE5u/Japgo/7SJV3PvgjGiRNAvTVGqQl8= +github.com/stretchr/testify v1.11.0/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/tdewolff/minify/v2 v2.24.3 h1:BaKgWSFLKbKDiUskbeRgbe2n5d1Ci1x3cN/eXna8zOA= +github.com/tdewolff/minify/v2 v2.24.3/go.mod h1:1JrCtoZXaDbqioQZfk3Jdmr0GPJKiU7c1Apmb+7tCeE= +github.com/tdewolff/parse/v2 v2.8.3 h1:5VbvtJ83cfb289A1HzRA9sf02iT8YyUwN84ezjkdY1I= +github.com/tdewolff/parse/v2 v2.8.3/go.mod h1:Hwlni2tiVNKyzR1o6nUs4FOF07URA+JLBLd6dlIXYqo= +github.com/tdewolff/test v1.0.11 h1:FdLbwQVHxqG16SlkGveC0JVyrJN62COWTRyUFzfbtBE= +github.com/tdewolff/test v1.0.11/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8= +github.com/testcontainers/testcontainers-go v0.39.0 h1:uCUJ5tA+fcxbFAB0uP3pIK3EJ2IjjDUHFSZ1H1UxAts= +github.com/testcontainers/testcontainers-go v0.39.0/go.mod h1:qmHpkG7H5uPf/EvOORKvS6EuDkBUPE3zpVGaH9NL7f8= +github.com/testcontainers/testcontainers-go/modules/redis v0.39.0 h1:p54qELdCx4Gftkxzf44k9RJRRhaO/S5ehP9zo8SUTLM= +github.com/testcontainers/testcontainers-go/modules/redis v0.39.0/go.mod h1:P1mTbHruHqAU2I26y0RADz1BitF59FLbQr7ceqN9bt4= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= +github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= +go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= +go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= +go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= +go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/avatar-upload/main.go b/avatar-upload/main.go new file mode 100644 index 0000000..1870754 --- /dev/null +++ b/avatar-upload/main.go @@ -0,0 +1,133 @@ +package main + +import ( + "context" + "embed" + "fmt" + "log" + "net/http" + "os" + "path/filepath" + + "github.com/livetemplate/livetemplate" +) + +//go:embed *.tmpl +var templates embed.FS + +// ProfileStore manages user profile with avatar upload +type ProfileStore struct { + Name string + Email string + AvatarPath string + AvatarURL string +} + +// AllowUploads configures avatar upload +func (s *ProfileStore) AllowUploads() map[string]livetemplate.UploadConfig { + return map[string]livetemplate.UploadConfig{ + "avatar": { + Accept: []string{"image/jpeg", "image/png", "image/gif"}, + MaxFileSize: 5 * 1024 * 1024, // 5MB + MaxEntries: 1, // Single file + AutoUpload: false, // Manual upload on form submit + ChunkSize: 256 * 1024, // 256KB chunks + }, + } +} + +// ConsumeUpload processes uploaded avatar +func (s *ProfileStore) ConsumeUpload(ctx context.Context, name string, entries []*livetemplate.UploadEntry) error { + if name != "avatar" { + return nil + } + + // Create uploads directory if it doesn't exist + uploadsDir := "uploads" + if err := os.MkdirAll(uploadsDir, 0755); err != nil { + return fmt.Errorf("failed to create uploads directory: %w", err) + } + + for _, entry := range entries { + // Generate permanent filename + ext := filepath.Ext(entry.ClientName) + permanentPath := filepath.Join(uploadsDir, fmt.Sprintf("avatar-%s%s", entry.ID, ext)) + + // Move from temp to permanent location + if err := os.Rename(entry.TempPath, permanentPath); err != nil { + // If rename fails (different filesystem), try copy + if err := copyFile(entry.TempPath, permanentPath); err != nil { + return fmt.Errorf("failed to save avatar: %w", err) + } + os.Remove(entry.TempPath) // Clean up temp file + } + + // Update store with new avatar + s.AvatarPath = permanentPath + s.AvatarURL = "/" + permanentPath + + log.Printf("Avatar saved: %s (original: %s, size: %d bytes)", permanentPath, entry.ClientName, entry.ClientSize) + } + + return nil +} + +// copyFile copies a file from src to dst +func copyFile(src, dst string) error { + data, err := os.ReadFile(src) + if err != nil { + return err + } + return os.WriteFile(dst, data, 0644) +} + +// UpdateProfile handles profile update form submission +func (s *ProfileStore) UpdateProfile(ctx context.Context, data livetemplate.ActionData) error { + name, _ := data.String("name") + email, _ := data.String("email") + + s.Name = name + s.Email = email + + log.Printf("Profile updated: name=%s, email=%s", s.Name, s.Email) + return nil +} + +func main() { + // Parse port from environment or use default + port := os.Getenv("PORT") + if port == "" { + port = "8080" + } + + // Create LiveTemplate instance + lt := livetemplate.Must(livetemplate.New("avatar-upload", + livetemplate.WithTemplateFS(templates), + livetemplate.WithDevMode(true), + ) + + // Create initial store + store := &ProfileStore{ + Name: "John Doe", + Email: "john@example.com", + } + + // Create handler with upload support + handler := lt.NewHandler(store) + + // Serve static files (for uploaded avatars) + http.Handle("/uploads/", http.StripPrefix("/uploads/", http.FileServer(http.Dir("uploads")))) + + // Mount the LiveTemplate handler + http.Handle("/", handler) + + // Start server + addr := ":" + port + log.Printf("🚀 Avatar upload example running at http://localhost%s", addr) + log.Printf("📸 Upload an avatar to see the upload feature in action!") + log.Printf("📁 Uploaded files will be saved to ./uploads/") + + if err := http.ListenAndServe(addr, nil); err != nil { + log.Fatal(err) + } +} diff --git a/avatar-upload/run.sh b/avatar-upload/run.sh new file mode 100755 index 0000000..99f21a5 --- /dev/null +++ b/avatar-upload/run.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# Simple script to run the avatar upload example + +cd "$(dirname "$0")" + +echo "🚀 Starting Avatar Upload Example..." +echo "📍 Server will run at http://localhost:8082" +echo "" + +# Set PORT and run +PORT=8082 go run main.go diff --git a/chat/main.go b/chat/main.go index ff856a7..6e6b417 100644 --- a/chat/main.go +++ b/chat/main.go @@ -148,7 +148,7 @@ func main() { // Uses default AnonymousAuthenticator - each browser gets its own session (via cookie) // Tabs in same browser share state // Configure via LVT_* environment variables (e.g., LVT_DEV_MODE=true) - tmpl := livetemplate.New("chat", envConfig.ToOptions()...) + tmpl := livetemplate.Must(livetemplate.New("chat", envConfig.ToOptions())...) // Mount handler http.Handle("/", tmpl.Handle(state)) diff --git a/counter/go.mod b/counter/go.mod index b858890..021ed53 100644 --- a/counter/go.mod +++ b/counter/go.mod @@ -31,4 +31,7 @@ require ( golang.org/x/net v0.46.0 // indirect golang.org/x/sys v0.37.0 // indirect golang.org/x/text v0.30.0 // indirect + golang.org/x/time v0.14.0 // indirect ) + +replace github.com/livetemplate/livetemplate => /Users/adnaan/code/livetemplate/livetemplate diff --git a/counter/go.sum b/counter/go.sum index ef2b61e..85c9a45 100644 --- a/counter/go.sum +++ b/counter/go.sum @@ -80,8 +80,6 @@ github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kUL github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/livetemplate/livetemplate v0.1.1 h1:DS8VXLOvdHqtSbk+Zr6+znCHgRvU9qD6os3ABY9DOlA= -github.com/livetemplate/livetemplate v0.1.1/go.mod h1:SobBok7X09b1oxEIHEAvABTRhGqRjCfMpUAY7E7XeHg= github.com/livetemplate/lvt v0.0.0-20251103195948-fbcd6dfae2d0 h1:WQcir+LsmAlaihnnRdLUiGefy2J+cnpoRMrzJgNoF4k= github.com/livetemplate/lvt v0.0.0-20251103195948-fbcd6dfae2d0/go.mod h1:+MkJVOR/rgGWe6xEVnjRSRCKhjM1KkpeaheqS9UHjM8= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= @@ -161,5 +159,7 @@ golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/counter/main.go b/counter/main.go index 06e4903..0e4b2d7 100644 --- a/counter/main.go +++ b/counter/main.go @@ -60,7 +60,7 @@ func main() { // Create template with environment-based configuration // Configuration is loaded from LVT_* environment variables - tmpl := livetemplate.New("counter", envConfig.ToOptions()...) + tmpl := livetemplate.Must(livetemplate.New("counter", envConfig.ToOptions())...) // Mount handler - auto-handles initial page, WebSocket, and HTTP actions http.Handle("/", tmpl.Handle(state)) diff --git a/graceful-shutdown/main.go b/graceful-shutdown/main.go index 551f943..d2c26d2 100644 --- a/graceful-shutdown/main.go +++ b/graceful-shutdown/main.go @@ -63,7 +63,7 @@ func main() { } // Create template with environment-based configuration - tmpl := livetemplate.New("counter", envConfig.ToOptions()...) + tmpl := livetemplate.Must(livetemplate.New("counter", envConfig.ToOptions())...) // Get the LiveHandler for shutdown control handler := tmpl.Handle(state) diff --git a/observability/main.go b/observability/main.go index ed05fb2..6b4cca1 100644 --- a/observability/main.go +++ b/observability/main.go @@ -119,7 +119,7 @@ func main() { // Create template with environment-based configuration // Template operations are now automatically logged! // Configuration is loaded from LVT_* environment variables - tmpl := livetemplate.New("counter", envConfig.ToOptions()...) + tmpl := livetemplate.Must(livetemplate.New("counter", envConfig.ToOptions())...) // Mount handler - auto-handles initial page, WebSocket, and HTTP actions // All actions and WebSocket events are now logged and metered! diff --git a/production/single-host/main.go b/production/single-host/main.go index af8c910..3cbe745 100644 --- a/production/single-host/main.go +++ b/production/single-host/main.go @@ -93,7 +93,7 @@ func main() { } // Create template - tmpl := livetemplate.New("app", envConfig.ToOptions()...) + tmpl := livetemplate.Must(livetemplate.New("app", envConfig.ToOptions())...) liveHandler := tmpl.Handle(state) // Setup HTTP routes with trace middleware diff --git a/testing/01_basic/main.go b/testing/01_basic/main.go index 25cdc05..607feb8 100644 --- a/testing/01_basic/main.go +++ b/testing/01_basic/main.go @@ -23,7 +23,7 @@ func (s *PageState) Change(ctx *livetemplate.ActionContext) error { func main() { // Create template - tmpl := livetemplate.New("welcome") + tmpl := livetemplate.Must(livetemplate.New("welcome")) // Parse template inline if _, err := tmpl.Parse(` diff --git a/todos/main.go b/todos/main.go index 7571b2d..1beb954 100644 --- a/todos/main.go +++ b/todos/main.go @@ -374,7 +374,7 @@ func main() { // Create template with environment-based configuration // Configuration is loaded from LVT_* environment variables - tmpl := livetemplate.New("todos", envConfig.ToOptions()...) + tmpl := livetemplate.Must(livetemplate.New("todos", envConfig.ToOptions())...) // Mount handler - auto-handles initial page, WebSocket, and HTTP actions http.Handle("/", tmpl.Handle(state)) diff --git a/trace-correlation/main.go b/trace-correlation/main.go index d681be2..e8418ed 100644 --- a/trace-correlation/main.go +++ b/trace-correlation/main.go @@ -97,7 +97,7 @@ func main() { } // Create template - tmpl := livetemplate.New("counter", envConfig.ToOptions()...) + tmpl := livetemplate.Must(livetemplate.New("counter", envConfig.ToOptions())...) liveHandler := tmpl.Handle(state) // Setup HTTP routes with trace middleware From 4ca9e3fcfb36ba7af396ce57a098378fee47637f Mon Sep 17 00:00:00 2001 From: Adnaan Date: Wed, 12 Nov 2025 19:09:54 +0100 Subject: [PATCH 2/5] chore: remove local replace directives from go.mod files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removed local replace directives that were used for development. These will be replaced with the official v0.3.0 release once tagged. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- avatar-upload/go.mod | 1 - counter/go.mod | 1 - 2 files changed, 2 deletions(-) diff --git a/avatar-upload/go.mod b/avatar-upload/go.mod index 1b390c9..bd8a7d1 100644 --- a/avatar-upload/go.mod +++ b/avatar-upload/go.mod @@ -42,4 +42,3 @@ require ( golang.org/x/time v0.14.0 // indirect ) -replace github.com/livetemplate/livetemplate => ../../livetemplate/.worktrees/feature-uploads diff --git a/counter/go.mod b/counter/go.mod index 021ed53..a28464b 100644 --- a/counter/go.mod +++ b/counter/go.mod @@ -34,4 +34,3 @@ require ( golang.org/x/time v0.14.0 // indirect ) -replace github.com/livetemplate/livetemplate => /Users/adnaan/code/livetemplate/livetemplate From 3bf50e806750960eef4382ac7b862dd0f305252e Mon Sep 17 00:00:00 2001 From: Adnaan Date: Wed, 12 Nov 2025 19:16:44 +0100 Subject: [PATCH 3/5] chore: upgrade to livetemplate v0.3.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updated all examples to use livetemplate v0.3.0 which includes the new Must(New()) pattern and other improvements. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- avatar-upload/go.mod | 19 ------------------ avatar-upload/go.sum | 38 ++--------------------------------- chat/go.mod | 3 ++- chat/go.sum | 6 ++++-- counter/go.mod | 3 +-- counter/go.sum | 2 ++ graceful-shutdown/go.mod | 3 ++- graceful-shutdown/go.sum | 6 ++++-- observability/go.mod | 3 ++- observability/go.sum | 6 ++++-- production/single-host/go.mod | 3 ++- production/single-host/go.sum | 6 ++++-- testing/01_basic/go.mod | 3 ++- testing/01_basic/go.sum | 6 ++++-- todos/go.mod | 3 ++- todos/go.sum | 6 ++++-- trace-correlation/go.mod | 3 ++- trace-correlation/go.sum | 6 ++++-- 18 files changed, 47 insertions(+), 78 deletions(-) diff --git a/avatar-upload/go.mod b/avatar-upload/go.mod index bd8a7d1..3d094e2 100644 --- a/avatar-upload/go.mod +++ b/avatar-upload/go.mod @@ -5,24 +5,6 @@ go 1.25.3 require github.com/livetemplate/livetemplate v0.3.0 require ( - github.com/aws/aws-sdk-go-v2 v1.39.6 // indirect - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.3 // indirect - github.com/aws/aws-sdk-go-v2/config v1.31.17 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.18.21 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.13 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.13 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.13 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.13 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.4 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.13 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.13 // indirect - github.com/aws/aws-sdk-go-v2/service/s3 v1.90.0 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.30.1 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.39.1 // indirect - github.com/aws/smithy-go v1.23.2 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/gabriel-vasile/mimetype v1.4.10 // indirect @@ -41,4 +23,3 @@ require ( golang.org/x/text v0.29.0 // indirect golang.org/x/time v0.14.0 // indirect ) - diff --git a/avatar-upload/go.sum b/avatar-upload/go.sum index de73ae4..1ea0169 100644 --- a/avatar-upload/go.sum +++ b/avatar-upload/go.sum @@ -4,42 +4,6 @@ github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOEl github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/aws/aws-sdk-go-v2 v1.39.6 h1:2JrPCVgWJm7bm83BDwY5z8ietmeJUbh3O2ACnn+Xsqk= -github.com/aws/aws-sdk-go-v2 v1.39.6/go.mod h1:c9pm7VwuW0UPxAEYGyTmyurVcNrbF6Rt/wixFqDhcjE= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.3 h1:DHctwEM8P8iTXFxC/QK0MRjwEpWQeM9yzidCRjldUz0= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.3/go.mod h1:xdCzcZEtnSTKVDOmUZs4l/j3pSV6rpo1WXl5ugNsL8Y= -github.com/aws/aws-sdk-go-v2/config v1.31.17 h1:QFl8lL6RgakNK86vusim14P2k8BFSxjvUkcWLDjgz9Y= -github.com/aws/aws-sdk-go-v2/config v1.31.17/go.mod h1:V8P7ILjp/Uef/aX8TjGk6OHZN6IKPM5YW6S78QnRD5c= -github.com/aws/aws-sdk-go-v2/credentials v1.18.21 h1:56HGpsgnmD+2/KpG0ikvvR8+3v3COCwaF4r+oWwOeNA= -github.com/aws/aws-sdk-go-v2/credentials v1.18.21/go.mod h1:3YELwedmQbw7cXNaII2Wywd+YY58AmLPwX4LzARgmmA= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.13 h1:T1brd5dR3/fzNFAQch/iBKeX07/ffu/cLu+q+RuzEWk= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.13/go.mod h1:Peg/GBAQ6JDt+RoBf4meB1wylmAipb7Kg2ZFakZTlwk= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.13 h1:a+8/MLcWlIxo1lF9xaGt3J/u3yOZx+CdSveSNwjhD40= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.13/go.mod h1:oGnKwIYZ4XttyU2JWxFrwvhF6YKiK/9/wmE3v3Iu9K8= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.13 h1:HBSI2kDkMdWz4ZM7FjwE7e/pWDEZ+nR95x8Ztet1ooY= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.13/go.mod h1:YE94ZoDArI7awZqJzBAZ3PDD2zSfuP7w6P2knOzIn8M= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.13 h1:eg/WYAa12vqTphzIdWMzqYRVKKnCboVPRlvaybNCqPA= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.13/go.mod h1:/FDdxWhz1486obGrKKC1HONd7krpk38LBt+dutLcN9k= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3 h1:x2Ibm/Af8Fi+BH+Hsn9TXGdT+hKbDd5XOTZxTMxDk7o= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3/go.mod h1:IW1jwyrQgMdhisceG8fQLmQIydcT/jWY21rFhzgaKwo= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.4 h1:NvMjwvv8hpGUILarKw7Z4Q0w1H9anXKsesMxtw++MA4= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.4/go.mod h1:455WPHSwaGj2waRSpQp7TsnpOnBfw8iDfPfbwl7KPJE= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.13 h1:kDqdFvMY4AtKoACfzIGD8A0+hbT41KTKF//gq7jITfM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.13/go.mod h1:lmKuogqSU3HzQCwZ9ZtcqOc5XGMqtDK7OIc2+DxiUEg= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.13 h1:zhBJXdhWIFZ1acfDYIhu4+LCzdUS2Vbcum7D01dXlHQ= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.13/go.mod h1:JaaOeCE368qn2Hzi3sEzY6FgAZVCIYcC2nwbro2QCh8= -github.com/aws/aws-sdk-go-v2/service/s3 v1.90.0 h1:ef6gIJR+xv/JQWwpa5FYirzoQctfSJm7tuDe3SZsUf8= -github.com/aws/aws-sdk-go-v2/service/s3 v1.90.0/go.mod h1:+wArOOrcHUevqdto9k1tKOF5++YTe9JEcPSc9Tx2ZSw= -github.com/aws/aws-sdk-go-v2/service/sso v1.30.1 h1:0JPwLz1J+5lEOfy/g0SURC9cxhbQ1lIMHMa+AHZSzz0= -github.com/aws/aws-sdk-go-v2/service/sso v1.30.1/go.mod h1:fKvyjJcz63iL/ftA6RaM8sRCtN4r4zl4tjL3qw5ec7k= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.5 h1:OWs0/j2UYR5LOGi88sD5/lhN6TDLG6SfA7CqsQO9zF0= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.5/go.mod h1:klO+ejMvYsB4QATfEOIXk8WAEwN4N0aBfJpvC+5SZBo= -github.com/aws/aws-sdk-go-v2/service/sts v1.39.1 h1:mLlUgHn02ue8whiR4BmxxGJLR2gwU6s6ZzJ5wDamBUs= -github.com/aws/aws-sdk-go-v2/service/sts v1.39.1/go.mod h1:E19xDjpzPZC7LS2knI9E6BaRFDK43Eul7vd6rSq2HWk= -github.com/aws/smithy-go v1.23.2 h1:Crv0eatJUQhaManss33hS5r40CG3ZFH+21XSkqMrIUM= -github.com/aws/smithy-go v1.23.2/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= @@ -100,6 +64,8 @@ github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zt github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/livetemplate/livetemplate v0.3.0 h1:k3cpsiOmWcjS+S/e5rvydbi6nY86ipnWd801B5hgL5M= +github.com/livetemplate/livetemplate v0.3.0/go.mod h1:PYS1hH2a6o7d9LID96780l/HHSGJIJS70kBnVO1mIUA= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE= diff --git a/chat/go.mod b/chat/go.mod index fca41b0..98ea487 100644 --- a/chat/go.mod +++ b/chat/go.mod @@ -4,7 +4,7 @@ go 1.25 require ( github.com/chromedp/chromedp v0.14.2 - github.com/livetemplate/livetemplate v0.1.1 + github.com/livetemplate/livetemplate v0.3.0 ) require ( @@ -30,6 +30,7 @@ require ( golang.org/x/net v0.44.0 // indirect golang.org/x/sys v0.36.0 // indirect golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.14.0 // indirect ) // TODO: Add github.com/livetemplate/lvt v0.1.0 after it's tagged diff --git a/chat/go.sum b/chat/go.sum index c06aa39..c26c4d1 100644 --- a/chat/go.sum +++ b/chat/go.sum @@ -80,8 +80,8 @@ github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kUL github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/livetemplate/livetemplate v0.1.1 h1:DS8VXLOvdHqtSbk+Zr6+znCHgRvU9qD6os3ABY9DOlA= -github.com/livetemplate/livetemplate v0.1.1/go.mod h1:SobBok7X09b1oxEIHEAvABTRhGqRjCfMpUAY7E7XeHg= +github.com/livetemplate/livetemplate v0.3.0 h1:k3cpsiOmWcjS+S/e5rvydbi6nY86ipnWd801B5hgL5M= +github.com/livetemplate/livetemplate v0.3.0/go.mod h1:PYS1hH2a6o7d9LID96780l/HHSGJIJS70kBnVO1mIUA= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE= @@ -159,5 +159,7 @@ golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/counter/go.mod b/counter/go.mod index a28464b..5b7d691 100644 --- a/counter/go.mod +++ b/counter/go.mod @@ -5,7 +5,7 @@ go 1.25 require ( github.com/chromedp/chromedp v0.14.2 github.com/gorilla/websocket v1.5.3 - github.com/livetemplate/livetemplate v0.1.1 + github.com/livetemplate/livetemplate v0.3.0 github.com/livetemplate/lvt v0.0.0-20251103195948-fbcd6dfae2d0 ) @@ -33,4 +33,3 @@ require ( golang.org/x/text v0.30.0 // indirect golang.org/x/time v0.14.0 // indirect ) - diff --git a/counter/go.sum b/counter/go.sum index 85c9a45..ddb7b28 100644 --- a/counter/go.sum +++ b/counter/go.sum @@ -80,6 +80,8 @@ github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kUL github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/livetemplate/livetemplate v0.3.0 h1:k3cpsiOmWcjS+S/e5rvydbi6nY86ipnWd801B5hgL5M= +github.com/livetemplate/livetemplate v0.3.0/go.mod h1:PYS1hH2a6o7d9LID96780l/HHSGJIJS70kBnVO1mIUA= github.com/livetemplate/lvt v0.0.0-20251103195948-fbcd6dfae2d0 h1:WQcir+LsmAlaihnnRdLUiGefy2J+cnpoRMrzJgNoF4k= github.com/livetemplate/lvt v0.0.0-20251103195948-fbcd6dfae2d0/go.mod h1:+MkJVOR/rgGWe6xEVnjRSRCKhjM1KkpeaheqS9UHjM8= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= diff --git a/graceful-shutdown/go.mod b/graceful-shutdown/go.mod index fa9b915..e4768aa 100644 --- a/graceful-shutdown/go.mod +++ b/graceful-shutdown/go.mod @@ -3,7 +3,7 @@ module graceful-shutdown go 1.25 require ( - github.com/livetemplate/livetemplate v0.1.1 + github.com/livetemplate/livetemplate v0.3.0 github.com/livetemplate/lvt v0.0.0-20251103195948-fbcd6dfae2d0 ) @@ -31,4 +31,5 @@ require ( golang.org/x/net v0.44.0 // indirect golang.org/x/sys v0.36.0 // indirect golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.14.0 // indirect ) diff --git a/graceful-shutdown/go.sum b/graceful-shutdown/go.sum index d0f43c1..090c207 100644 --- a/graceful-shutdown/go.sum +++ b/graceful-shutdown/go.sum @@ -80,8 +80,8 @@ github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kUL github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/livetemplate/livetemplate v0.1.1 h1:DS8VXLOvdHqtSbk+Zr6+znCHgRvU9qD6os3ABY9DOlA= -github.com/livetemplate/livetemplate v0.1.1/go.mod h1:SobBok7X09b1oxEIHEAvABTRhGqRjCfMpUAY7E7XeHg= +github.com/livetemplate/livetemplate v0.3.0 h1:k3cpsiOmWcjS+S/e5rvydbi6nY86ipnWd801B5hgL5M= +github.com/livetemplate/livetemplate v0.3.0/go.mod h1:PYS1hH2a6o7d9LID96780l/HHSGJIJS70kBnVO1mIUA= github.com/livetemplate/lvt v0.0.0-20251103195948-fbcd6dfae2d0 h1:WQcir+LsmAlaihnnRdLUiGefy2J+cnpoRMrzJgNoF4k= github.com/livetemplate/lvt v0.0.0-20251103195948-fbcd6dfae2d0/go.mod h1:+MkJVOR/rgGWe6xEVnjRSRCKhjM1KkpeaheqS9UHjM8= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= @@ -161,5 +161,7 @@ golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/observability/go.mod b/observability/go.mod index 2f0e03a..6fdb33c 100644 --- a/observability/go.mod +++ b/observability/go.mod @@ -3,7 +3,7 @@ module observability go 1.25 require ( - github.com/livetemplate/livetemplate v0.1.1 + github.com/livetemplate/livetemplate v0.3.0 github.com/livetemplate/lvt v0.0.0-20251103070549-7ffea37f50da ) @@ -31,6 +31,7 @@ require ( golang.org/x/net v0.44.0 // indirect golang.org/x/sys v0.36.0 // indirect golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.14.0 // indirect ) // TODO: Add github.com/livetemplate/lvt v0.1.0 after it's tagged diff --git a/observability/go.sum b/observability/go.sum index 1ad4ca6..8fbd5b2 100644 --- a/observability/go.sum +++ b/observability/go.sum @@ -80,8 +80,8 @@ github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kUL github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/livetemplate/livetemplate v0.1.1 h1:DS8VXLOvdHqtSbk+Zr6+znCHgRvU9qD6os3ABY9DOlA= -github.com/livetemplate/livetemplate v0.1.1/go.mod h1:SobBok7X09b1oxEIHEAvABTRhGqRjCfMpUAY7E7XeHg= +github.com/livetemplate/livetemplate v0.3.0 h1:k3cpsiOmWcjS+S/e5rvydbi6nY86ipnWd801B5hgL5M= +github.com/livetemplate/livetemplate v0.3.0/go.mod h1:PYS1hH2a6o7d9LID96780l/HHSGJIJS70kBnVO1mIUA= github.com/livetemplate/lvt v0.0.0-20251103070549-7ffea37f50da h1:ZONdEpB9vxj4xyJlQ1t3I/sIxkllrKu5fWadFL60nsA= github.com/livetemplate/lvt v0.0.0-20251103070549-7ffea37f50da/go.mod h1:1/HRPggC3loru3AB6GYQdMWP1bJhuCGZERD36GlLEw0= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= @@ -161,5 +161,7 @@ golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/production/single-host/go.mod b/production/single-host/go.mod index b1660c2..be593f9 100644 --- a/production/single-host/go.mod +++ b/production/single-host/go.mod @@ -3,7 +3,7 @@ module single-host go 1.25 require ( - github.com/livetemplate/livetemplate v0.1.1 + github.com/livetemplate/livetemplate v0.3.0 github.com/livetemplate/lvt v0.0.0-20251103070549-7ffea37f50da ) @@ -31,6 +31,7 @@ require ( golang.org/x/net v0.44.0 // indirect golang.org/x/sys v0.36.0 // indirect golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.14.0 // indirect ) // TODO: Add github.com/livetemplate/lvt v0.1.0 after it's tagged diff --git a/production/single-host/go.sum b/production/single-host/go.sum index 1ad4ca6..8fbd5b2 100644 --- a/production/single-host/go.sum +++ b/production/single-host/go.sum @@ -80,8 +80,8 @@ github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kUL github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/livetemplate/livetemplate v0.1.1 h1:DS8VXLOvdHqtSbk+Zr6+znCHgRvU9qD6os3ABY9DOlA= -github.com/livetemplate/livetemplate v0.1.1/go.mod h1:SobBok7X09b1oxEIHEAvABTRhGqRjCfMpUAY7E7XeHg= +github.com/livetemplate/livetemplate v0.3.0 h1:k3cpsiOmWcjS+S/e5rvydbi6nY86ipnWd801B5hgL5M= +github.com/livetemplate/livetemplate v0.3.0/go.mod h1:PYS1hH2a6o7d9LID96780l/HHSGJIJS70kBnVO1mIUA= github.com/livetemplate/lvt v0.0.0-20251103070549-7ffea37f50da h1:ZONdEpB9vxj4xyJlQ1t3I/sIxkllrKu5fWadFL60nsA= github.com/livetemplate/lvt v0.0.0-20251103070549-7ffea37f50da/go.mod h1:1/HRPggC3loru3AB6GYQdMWP1bJhuCGZERD36GlLEw0= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= @@ -161,5 +161,7 @@ golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/testing/01_basic/go.mod b/testing/01_basic/go.mod index 6c0d761..2ce2d1b 100644 --- a/testing/01_basic/go.mod +++ b/testing/01_basic/go.mod @@ -3,7 +3,7 @@ module basic go 1.25 require ( - github.com/livetemplate/livetemplate v0.1.1 + github.com/livetemplate/livetemplate v0.3.0 github.com/livetemplate/lvt v0.0.0-20251103195948-fbcd6dfae2d0 ) @@ -31,6 +31,7 @@ require ( golang.org/x/net v0.44.0 // indirect golang.org/x/sys v0.36.0 // indirect golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.14.0 // indirect ) // TODO: Add github.com/livetemplate/lvt v0.1.0 after it's tagged diff --git a/testing/01_basic/go.sum b/testing/01_basic/go.sum index d0f43c1..090c207 100644 --- a/testing/01_basic/go.sum +++ b/testing/01_basic/go.sum @@ -80,8 +80,8 @@ github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kUL github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/livetemplate/livetemplate v0.1.1 h1:DS8VXLOvdHqtSbk+Zr6+znCHgRvU9qD6os3ABY9DOlA= -github.com/livetemplate/livetemplate v0.1.1/go.mod h1:SobBok7X09b1oxEIHEAvABTRhGqRjCfMpUAY7E7XeHg= +github.com/livetemplate/livetemplate v0.3.0 h1:k3cpsiOmWcjS+S/e5rvydbi6nY86ipnWd801B5hgL5M= +github.com/livetemplate/livetemplate v0.3.0/go.mod h1:PYS1hH2a6o7d9LID96780l/HHSGJIJS70kBnVO1mIUA= github.com/livetemplate/lvt v0.0.0-20251103195948-fbcd6dfae2d0 h1:WQcir+LsmAlaihnnRdLUiGefy2J+cnpoRMrzJgNoF4k= github.com/livetemplate/lvt v0.0.0-20251103195948-fbcd6dfae2d0/go.mod h1:+MkJVOR/rgGWe6xEVnjRSRCKhjM1KkpeaheqS9UHjM8= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= @@ -161,5 +161,7 @@ golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/todos/go.mod b/todos/go.mod index e1bd64a..0d42914 100644 --- a/todos/go.mod +++ b/todos/go.mod @@ -6,7 +6,7 @@ require ( github.com/chromedp/chromedp v0.14.2 github.com/go-playground/validator/v10 v10.28.0 github.com/gorilla/websocket v1.5.3 - github.com/livetemplate/livetemplate v0.1.1 + github.com/livetemplate/livetemplate v0.3.0 github.com/livetemplate/lvt v0.0.0-20251103195948-fbcd6dfae2d0 modernc.org/sqlite v1.39.1 ) @@ -37,6 +37,7 @@ require ( golang.org/x/net v0.46.0 // indirect golang.org/x/sys v0.37.0 // indirect golang.org/x/text v0.30.0 // indirect + golang.org/x/time v0.14.0 // indirect modernc.org/libc v1.66.10 // indirect modernc.org/mathutil v1.7.1 // indirect modernc.org/memory v1.11.0 // indirect diff --git a/todos/go.sum b/todos/go.sum index 4f9f7c0..49e92b3 100644 --- a/todos/go.sum +++ b/todos/go.sum @@ -84,8 +84,8 @@ github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kUL github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/livetemplate/livetemplate v0.1.1 h1:DS8VXLOvdHqtSbk+Zr6+znCHgRvU9qD6os3ABY9DOlA= -github.com/livetemplate/livetemplate v0.1.1/go.mod h1:SobBok7X09b1oxEIHEAvABTRhGqRjCfMpUAY7E7XeHg= +github.com/livetemplate/livetemplate v0.3.0 h1:k3cpsiOmWcjS+S/e5rvydbi6nY86ipnWd801B5hgL5M= +github.com/livetemplate/livetemplate v0.3.0/go.mod h1:PYS1hH2a6o7d9LID96780l/HHSGJIJS70kBnVO1mIUA= github.com/livetemplate/lvt v0.0.0-20251103195948-fbcd6dfae2d0 h1:WQcir+LsmAlaihnnRdLUiGefy2J+cnpoRMrzJgNoF4k= github.com/livetemplate/lvt v0.0.0-20251103195948-fbcd6dfae2d0/go.mod h1:+MkJVOR/rgGWe6xEVnjRSRCKhjM1KkpeaheqS9UHjM8= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= @@ -177,6 +177,8 @@ golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/trace-correlation/go.mod b/trace-correlation/go.mod index 0f0d7c2..da58973 100644 --- a/trace-correlation/go.mod +++ b/trace-correlation/go.mod @@ -3,7 +3,7 @@ module trace-correlation go 1.25 require ( - github.com/livetemplate/livetemplate v0.1.1 + github.com/livetemplate/livetemplate v0.3.0 github.com/livetemplate/lvt v0.0.0-20251103070549-7ffea37f50da ) @@ -31,6 +31,7 @@ require ( golang.org/x/net v0.44.0 // indirect golang.org/x/sys v0.36.0 // indirect golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.14.0 // indirect ) // TODO: Add github.com/livetemplate/lvt v0.1.0 after it's tagged diff --git a/trace-correlation/go.sum b/trace-correlation/go.sum index 1ad4ca6..8fbd5b2 100644 --- a/trace-correlation/go.sum +++ b/trace-correlation/go.sum @@ -80,8 +80,8 @@ github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kUL github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/livetemplate/livetemplate v0.1.1 h1:DS8VXLOvdHqtSbk+Zr6+znCHgRvU9qD6os3ABY9DOlA= -github.com/livetemplate/livetemplate v0.1.1/go.mod h1:SobBok7X09b1oxEIHEAvABTRhGqRjCfMpUAY7E7XeHg= +github.com/livetemplate/livetemplate v0.3.0 h1:k3cpsiOmWcjS+S/e5rvydbi6nY86ipnWd801B5hgL5M= +github.com/livetemplate/livetemplate v0.3.0/go.mod h1:PYS1hH2a6o7d9LID96780l/HHSGJIJS70kBnVO1mIUA= github.com/livetemplate/lvt v0.0.0-20251103070549-7ffea37f50da h1:ZONdEpB9vxj4xyJlQ1t3I/sIxkllrKu5fWadFL60nsA= github.com/livetemplate/lvt v0.0.0-20251103070549-7ffea37f50da/go.mod h1:1/HRPggC3loru3AB6GYQdMWP1bJhuCGZERD36GlLEw0= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= @@ -161,5 +161,7 @@ golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 20a6298dc1577ae0497601e6ab49656fbee24756 Mon Sep 17 00:00:00 2001 From: Adnaan Date: Wed, 12 Nov 2025 19:24:43 +0100 Subject: [PATCH 4/5] fix: correct Must(New()) variadic syntax MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed incorrect placement of spread operator in Must(New()) calls. The spread operator (...) should be inside New() to spread the options array, not outside Must(). Before: Must(New("name", opts)...) After: Must(New("name", opts...)) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- chat/main.go | 2 +- counter/main.go | 2 +- graceful-shutdown/main.go | 2 +- observability/main.go | 2 +- production/single-host/main.go | 2 +- todos/main.go | 2 +- trace-correlation/main.go | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/chat/main.go b/chat/main.go index 6e6b417..9f73f26 100644 --- a/chat/main.go +++ b/chat/main.go @@ -148,7 +148,7 @@ func main() { // Uses default AnonymousAuthenticator - each browser gets its own session (via cookie) // Tabs in same browser share state // Configure via LVT_* environment variables (e.g., LVT_DEV_MODE=true) - tmpl := livetemplate.Must(livetemplate.New("chat", envConfig.ToOptions())...) + tmpl := livetemplate.Must(livetemplate.New("chat", envConfig.ToOptions()...)) // Mount handler http.Handle("/", tmpl.Handle(state)) diff --git a/counter/main.go b/counter/main.go index 0e4b2d7..59c90de 100644 --- a/counter/main.go +++ b/counter/main.go @@ -60,7 +60,7 @@ func main() { // Create template with environment-based configuration // Configuration is loaded from LVT_* environment variables - tmpl := livetemplate.Must(livetemplate.New("counter", envConfig.ToOptions())...) + tmpl := livetemplate.Must(livetemplate.New("counter", envConfig.ToOptions()...)) // Mount handler - auto-handles initial page, WebSocket, and HTTP actions http.Handle("/", tmpl.Handle(state)) diff --git a/graceful-shutdown/main.go b/graceful-shutdown/main.go index d2c26d2..8ca92ad 100644 --- a/graceful-shutdown/main.go +++ b/graceful-shutdown/main.go @@ -63,7 +63,7 @@ func main() { } // Create template with environment-based configuration - tmpl := livetemplate.Must(livetemplate.New("counter", envConfig.ToOptions())...) + tmpl := livetemplate.Must(livetemplate.New("counter", envConfig.ToOptions()...)) // Get the LiveHandler for shutdown control handler := tmpl.Handle(state) diff --git a/observability/main.go b/observability/main.go index 6b4cca1..c68b512 100644 --- a/observability/main.go +++ b/observability/main.go @@ -119,7 +119,7 @@ func main() { // Create template with environment-based configuration // Template operations are now automatically logged! // Configuration is loaded from LVT_* environment variables - tmpl := livetemplate.Must(livetemplate.New("counter", envConfig.ToOptions())...) + tmpl := livetemplate.Must(livetemplate.New("counter", envConfig.ToOptions()...)) // Mount handler - auto-handles initial page, WebSocket, and HTTP actions // All actions and WebSocket events are now logged and metered! diff --git a/production/single-host/main.go b/production/single-host/main.go index 3cbe745..e0210d4 100644 --- a/production/single-host/main.go +++ b/production/single-host/main.go @@ -93,7 +93,7 @@ func main() { } // Create template - tmpl := livetemplate.Must(livetemplate.New("app", envConfig.ToOptions())...) + tmpl := livetemplate.Must(livetemplate.New("app", envConfig.ToOptions()...)) liveHandler := tmpl.Handle(state) // Setup HTTP routes with trace middleware diff --git a/todos/main.go b/todos/main.go index 1beb954..7526262 100644 --- a/todos/main.go +++ b/todos/main.go @@ -374,7 +374,7 @@ func main() { // Create template with environment-based configuration // Configuration is loaded from LVT_* environment variables - tmpl := livetemplate.Must(livetemplate.New("todos", envConfig.ToOptions())...) + tmpl := livetemplate.Must(livetemplate.New("todos", envConfig.ToOptions()...)) // Mount handler - auto-handles initial page, WebSocket, and HTTP actions http.Handle("/", tmpl.Handle(state)) diff --git a/trace-correlation/main.go b/trace-correlation/main.go index e8418ed..7000748 100644 --- a/trace-correlation/main.go +++ b/trace-correlation/main.go @@ -97,7 +97,7 @@ func main() { } // Create template - tmpl := livetemplate.Must(livetemplate.New("counter", envConfig.ToOptions())...) + tmpl := livetemplate.Must(livetemplate.New("counter", envConfig.ToOptions()...)) liveHandler := tmpl.Handle(state) // Setup HTTP routes with trace middleware From ba5120df3f227a22f75c88dbf717d41fb2d17ec2 Mon Sep 17 00:00:00 2001 From: Adnaan Date: Wed, 12 Nov 2025 19:31:46 +0100 Subject: [PATCH 5/5] fix: add template file for testing/01_basic example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added welcome.tmpl file to fix test failure. The New() function requires template files to exist for auto-discovery. Instead of using inline templates via Parse(), we now use a proper template file. This fixes the "Server failed to start within 5 seconds" error in TestBasicE2E. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- testing/01_basic/main.go | 20 +------------------- testing/01_basic/welcome.tmpl | 12 ++++++++++++ 2 files changed, 13 insertions(+), 19 deletions(-) create mode 100644 testing/01_basic/welcome.tmpl diff --git a/testing/01_basic/main.go b/testing/01_basic/main.go index 607feb8..7f3280c 100644 --- a/testing/01_basic/main.go +++ b/testing/01_basic/main.go @@ -22,27 +22,9 @@ func (s *PageState) Change(ctx *livetemplate.ActionContext) error { } func main() { - // Create template + // Create template (will auto-discover welcome.tmpl) tmpl := livetemplate.Must(livetemplate.New("welcome")) - // Parse template inline - if _, err := tmpl.Parse(` - - - - {{.Title}} - - -

{{.Title}}

-

{{.Message}}

-

Count: {{.Count}}

- - - - `); err != nil { - log.Fatal(err) - } - // Create state state := &PageState{ Title: "Welcome", diff --git a/testing/01_basic/welcome.tmpl b/testing/01_basic/welcome.tmpl new file mode 100644 index 0000000..b2e8003 --- /dev/null +++ b/testing/01_basic/welcome.tmpl @@ -0,0 +1,12 @@ + + + + {{.Title}} + + +

{{.Title}}

+

{{.Message}}

+

Count: {{.Count}}

+ + +