Repository navigation
feat: keep every display in step with one revision counter per kind of data (#325) - #339
Merged
Merged
Conversation
…f data (#325) A change on one display now shows on the others within 15 seconds on any install, and within a second where the event stream reaches the browser. Server (utils/householdChanges.js): - A revision counter for each kind of household data: chores, users, prizes, settings, calendar. An onResponse hook moves them for every successful write under the household routes, so no route can forget; a chore or prize write also moves users, for clam totals. The nightly job, calendar sync (only when the cache changed) and calendar routines move them too. Counters start from a random base, so a restart reads as everything changed. - GET /api/changes returns them with an ETag, and 304 when nothing moved. - Each burst of changes goes out on the event stream as household.changed { domains, revisions }, a new catalog event plugins can declare. Client (utils/householdChanges.js): - A display checks GET /api/changes every 15 seconds while visible and at once when it becomes visible again; a phone checks only when it becomes visible. The stream's household.changed is the fast path; both feed one deduplicated notification. - Coarse by design: subscribers learn which kinds moved and reload them. The Chores widget reloads on chores, users, prizes or settings; the calendar and the screensaver agenda on calendar; household settings (appearance, vacation, control limits) on settings; plugins that declare household.changed are told. Co-Authored-By: Claude Opus 5.5 <[email protected]>
adamecker
pushed a commit
to adamecker/HomeGlow
that referenced
this pull request
Oct 26, 2026
… revision counter jherforth#339, dimming jherforth#334, Save layout jherforth#336, chore perf jherforth#324, admin jherforth#330/jherforth#331/jherforth#332, PIN hardening jherforth#329 Conflicts resolved taking upstream's rewrite, preserving fork(prod) features: - displayDim.js: upstream jherforth#334 base plus fork-only kiosk URL dim overrides and LCD pixel shift (both absent upstream) - ChoreWidget/app.jsx/ChoreSchedulesTab: upstream jherforth#324/jherforth#336 rework
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements #325, with the decisions from the issue:
What it does
A change on one display (a chore ticked, a prize approved, vacation turned on, a calendar event added) shows on every other display:
The nightly job and calendar sync reach every display the same way.
Server:
utils/householdChanges.jschores,users,prizes,settingsandcalendar.onResponsehook moves the counters for every successful write under the household routes, so no route can forget to.users, because it changes clam totals./api/settings/search, a calendar source's test).GET /api/changes:{ chores, users, prizes, settings, calendar }with anETag, and304when nothing moved. The counters start from a random base, so after a restart every display reloads everything once.household.changed{ domains, revisions }, coalesced over 100 ms. It's a new catalog event that plugins can declare.Client:
utils/householdChanges.jshousehold.changedfeeds the same notification, so a change is reported once, whichever saw it first.household.changed: they're told which kinds changed.Left out on purpose
Worth knowing: every display now keeps the event stream open, not only those with event-subscribing plugins. Where the stream doesn't reach the browser, nothing breaks; the 15-second checks carry it.
Testing
Edge, two displays on one server, demo data. 8 of 8 checks pass:
304while nothing changes;Server tests:
householdChanges.test.js: the route mapping, reads and failures, coalescing, the random base;householdChangesRoutes.test.js, on a real server:304with the ETag, each write moving its kinds (a completion moves chores and users), reads and failures moving nothing, the nightly job, and the stream event;Server
npm test: 656 pass.Client tests:
householdChanges.test.js: notifications only for the kinds asked for, the baseline,If-None-Matchand304, a restart, the 15-second cadence and visibility, the phone mode, stopping with the last subscriber, and recovery after a failed check. Clientvitest(795),check:i18nandbuildpass.Dev setup: the dev server is cross-origin, so
If-None-Matchis allowed andETagexposed for it. Production is same-origin.Closes #325.
🤖 Generated with Claude Code