feat: migrate to selective persistence (lvt:"persist" tag)#44
Conversation
- Add lvt:"persist" to CounterState.Counter and LastUpdated fields - Delete ephemeral-counter/ and ephemeral-todos/ (redundant — no persist tags = ephemeral by default in new library) - Update test-all.sh and README.md to remove ephemeral examples - Update go.mod to livetemplate@selective-persist branch Closes #43 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Migrates the examples repository to LiveTemplate’s new selective persistence model by persisting only explicitly tagged state fields, removing now-redundant “ephemeral-*” examples, and updating dependency/tooling to track the upstream change.
Changes:
- Add
lvt:"persist"tags tocounter/state fields so the counter value survives refresh. - Remove
ephemeral-counter/andephemeral-todos/examples and their E2E tests; updatetest-all.shand the README list. - Update
go.mod/go.sumto a LiveTemplate version that includes selective persistence.
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
counter/main.go |
Marks Counter and LastUpdated as selectively persisted state. |
test-all.sh |
Removes deleted ephemeral examples from the working examples list. |
README.md |
Removes deleted ephemeral examples from the examples table. |
go.mod |
Bumps github.com/livetemplate/livetemplate to a version containing selective persistence. |
go.sum |
Adds checksums for the updated livetemplate version. |
ephemeral-counter/main.go |
Deleted redundant ephemeral counter example (previously used WithEphemeralState()). |
ephemeral-counter/counter.tmpl |
Deleted template for the removed example. |
ephemeral-counter/counter_test.go |
Deleted E2E test for the removed example. |
ephemeral-todos/main.go |
Deleted redundant ephemeral todos example (previously used WithEphemeralState()). |
ephemeral-todos/todos.tmpl |
Deleted template for the removed example. |
ephemeral-todos/todos_test.go |
Deleted E2E test for the removed example. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
counter/main.go
Outdated
| @@ -20,8 +20,8 @@ type CounterController struct{} | |||
| // CounterState is pure data, cloned per session. | |||
| type CounterState struct { | |||
| Title string `json:"title"` | |||
There was a problem hiding this comment.
With selective persistence, fields without lvt:"persist" are zeroed on reload and must be rehydrated via Mount(). Title is used by the template but is not tagged and there is no Mount() method here, so after a browser refresh the page title/header may become empty. Consider either tagging Title with lvt:"persist" as well, or adding a Mount() that always sets Title (and any other ephemeral defaults).
| Title string `json:"title"` | |
| Title string `json:"title" lvt:"persist"` |
| | `ws-disabled/` | 1 | HTTP-only mode | None | | ||
| | `live-preview/` | 1 | Change() live updates | None | | ||
| | `login/` | 1 | Authentication + sessions | None | | ||
| | `shared-notepad/` | 1 | BasicAuth + SharedState | None | | ||
| | `ephemeral-counter/` | 1 | Ephemeral state with in-memory DB | None | | ||
| | `ephemeral-todos/` | 1 | Ephemeral state with SQLite DB | None | | ||
|
|
There was a problem hiding this comment.
The PR description indicates a broader migration to selective persistence (and even closes #43), but the README table doesn’t document which examples now use lvt:"persist", and the repo currently only has lvt:"persist" tags in counter/. If chat/, todos/, and todos-progressive/ are expected to preserve UI/session state across refresh under the new default-ephemeral behavior, they will need persist tags (or the PR/issue closure should be adjusted to reflect a partial migration).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add persist tags to state fields that must survive HTTP POST→redirect→GET cycles. Fields loaded fresh by Mount() or from DB are left untagged. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Counter, todos, and todos-components set Title via initial state with no Mount() method. On returning sessions, restorePersistedState creates a zero-value struct with only persist fields — Title was lost. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Toasts and DeleteConfirm are component objects that can't survive JSON serialization. Add Mount() to re-initialize them on restored sessions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
lvt:"persist"toCounterState.CounterandCounterState.LastUpdatedso counter value survives page refreshephemeral-counter/andephemeral-todos/— redundant since no persist tags = ephemeral by defaulttest-all.shandREADME.mdgo.modatlivetemplate@selective-persistbranchDepends on: livetemplate/livetemplate#308
Test plan
CounterandLastUpdatedtaggedlvt:"persist"— survives refreshCloses #43
🤖 Generated with Claude Code