From 2119695e5de95279d2e2021578bd988f3d015d1a Mon Sep 17 00:00:00 2001 From: adnaan <758447+adnaan@users.noreply.github.com> Date: Wed, 4 Nov 2026 07:36:07 +0000 Subject: [PATCH] Sync from client@v0.25.2 --- content/changelog/client.md | 96 +++++++++++++++++++++++++++++++++- content/client/index.md | 6 +-- content/contributing/client.md | 4 +- 3 files changed, 99 insertions(+), 7 deletions(-) diff --git a/content/changelog/client.md b/content/changelog/client.md index 809cb88..109af7a 100644 --- a/content/changelog/client.md +++ b/content/changelog/client.md @@ -2,8 +2,8 @@ title: "Changelog" source_repo: "https://github.com/livetemplate/client" source_path: "CHANGELOG.md" -source_ref: "v0.25.0" -source_commit: "bcaba2b8bc6062bdcb56045d3b0ba5bc052ef77d" +source_ref: "v0.25.2" +source_commit: "0c16ab77ade82094f5918fb5f0b65c0bc12249a1" --- # Changelog @@ -13,6 +13,98 @@ All notable changes to @livetemplate/client will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v0.25.2] - 2026-11-04 + +### Fixed + +- **A failed reconnect no longer freezes the page until a reload (#160).** When + a live socket dropped and the reconnect ran while the network was still down + (a phone waking from sleep, a Wi-Fi blip), the client fell back to HTTP mode + and never tried the WebSocket again — the heartbeat and visibility paths both + skip HTTP mode — so server pushes stopped until the user reloaded. The client + now keeps retrying: on the next heartbeat tick (then backing off, capped at + 5 minutes), on a return to visible, on `pageshow`, and on the browser's + `online` event. Actions still go over HTTP in the meantime. A server that + reports no WebSocket at all, or a socket that fails on the very first connect, + still falls back to HTTP for good, as before. An app that opted out of the + heartbeat (`data-lvt-heartbeat-ms="0"`) gets no timed retries — it recovers + on `online`, a return to visible, or `pageshow` only. + +## [v0.25.1] - 2026-09-06 + +### Added + +- **`lvt-*` attributes are now extensible: `LiveTemplateClient.registerAttribute()`.** + Adding an attribute used to mean forking this library — writing a `dom/*.ts` + module, importing it into `livetemplate-client.ts`, and inserting a call at the + right position in a hardcoded ~20-entry sequence. An app that wanted + `lvt-x:copy-to-clipboard` had no supported way to get one. + + There are two layers. Most authors only need the declarative one: declare an + attribute *name* and get called per element. + + ```html + + + + ``` + + The framework owns selector escaping, the DOM scan, per-element match + tracking, empty-value rejection, and sweeping elements that lost the attribute + or left the DOM — the sweep runs on every render, so `onElementRemoved` is + never deferred — so the three classic mistakes (no sweep, listeners stacking + on every render, a captured transport that dies at reconnect) are not + reachable from this layer. `ctx.value` and `ctx.send` are live accessors, so a + listener wired once still reads the current attribute value and dispatches + through the current transport. + + Set `needsServerChannel: true` to get `ctx.send`; the message routes through + the same path an `lvt-on:click` action uses, and the server cannot tell the + difference. No server-side registration, no new wire message type, no build + step. + + A `selectors` + `setup()`/`teardown()` escape hatch covers handlers with + cross-element state; every built-in uses it, so an author is never on a lesser + API than the framework itself. + + Registration is static and late registration is supported: calling + `registerAttribute` after the client has connected runs the handler against + the live DOM immediately, rather than waiting for the next render. That is the + only sequence available to a second `