Repository navigation
fix(compression): merge engines writes by id instead of replacing the row - #15613
Merged
diegosouzapw merged 9 commits intoOct 6, 2026
Conversation
updateCompressionSettings stores whatever engines map it receives as the whole row, and the read path turns every id missing from that row off. These tests fail on the current base: a write carrying one engine turns the other stored engines off, a panel toggle after an Omniglyph toggle turns Omniglyph back off, a write that sets only enabled drops the stored level, and the first engines write on an install with no engines row drops the engines derived from legacy settings.
The Omniglyph page and the context settings panel PUT the whole engines map from the copy each loaded, so a toggle on one page overwrites what the other changed after it loaded. These tests expect each page to send only the engine it changed. The Omniglyph tests also expect a failed save to put the switch back, and the saved-status timer of an earlier save to leave a later save's error on screen. All fail on the current base.
… row updateCompressionSettings stored the engines map it received as the whole row, and the read path turns every id missing from that row off. The Omniglyph page and the context settings panel each PUT the full map from the copy they loaded, so a toggle on one page reverted engine changes the other page made after it loaded, and a toggle after a failed GET stored a map holding one engine and turned every other engine off. The write path now merges each written entry over the stored entry, field by field. While no engines row exists it merges over the map the read path derives from legacy settings, the map the dashboard shows. Both pages send only the engine they changed. The Omniglyph page also puts the switch back when a save fails, and its saved-status timer clears the status only when no later save has started.
Two default-route tests wrote only the engines they wanted on and relied on the write turning every other engine off. Writes now merge over the engines the install already has, so these tests write every engine id with the rest set off.
…ression-engines-partial-write
The requestBody schema never listed `engines`, and nothing said the PUT merges per engine id instead of replacing the stored map. Document the entry shape (enabled required, level optional and kept when omitted) and the legacy-derived fallback base used while no engines row is stored.
…cted saves Review findings: the write-path guard that treats a non-text engines row as absent had no case seeding one, the rewritten Omniglyph toggle was only exercised turning on, and a rejected fetch (as opposed to a non-ok response) was never saved. Each case pins existing behavior.
diegosouzapw
merged commit Oct 6, 2026
e1e9230
into
diegosouzapw:release/v3.8.52
42 of 51 checks passed
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.
Summary
PUT /api/settings/compressionstored theenginesmap it received, whole. The two dashboard pages that toggle compression engines (/dashboard/context/omniglyphand/dashboard/context/settings) each kept their own copy of the map from page load and sent it back complete, so a toggle made on one page was overwritten by the next toggle on the other page, or by the next toggle after a failed settings GET, which silently rebuilt the map from defaults. The server now merges each written engine entry over the stored entry by engine id, field by field. While no engines row is stored yet, the merge base is the map the read path derives from the legacy per-engine settings.save(body, rollback)helper with a generation counter, so the 2-second "Saved." timer of an earlier save can no longer clear a later save's error, and a failed save (non-ok response or rejected fetch) rolls the toggle back.docs/openapi.yamlnow documents the PUT'senginesbody property and the merge semantics; the requestBody never listedengines.enginesrow inkey_valueis treated as absent by the write path, matching the read path.Related Issues
fix/compression-panel-partial-save(which rewrites the panel'ssave()) and fix(compression): show a retry when settings fail to load #15346 (which leavessave()andsetEngineuntouched).git merge-treeagainst the currentrelease/v3.8.52tip (23a1148) is clean, and the fix(compression): show a retry when settings fail to load #15346 trial merge with this branch passed its compression UI suites.Validation
node --testonengines-partial-write.test.ts+context-combos-default-route.test.ts: 10/10.npx vitest runonomniglyphContextPage.test.tsx,compressionPanelEnginesPartialWrite.test.tsx,compressionPanel.test.tsx: 14/14.npx prettier --checkon the changed files is clean.Tests Added Or Updated
tests/unit/compression/engines-partial-write.test.ts(5 cases): stored engines survive a single-engine write; a toggle made on one page survives the other page's write; a storedlevelsurvives a write that only setsenabled; the first engines write merges over the legacy-derived map; a BLOB engines row is treated as absent.tests/unit/ui/omniglyphContextPage.test.tsx(7 cases): enabling sends only{ engines: { omniglyph: { enabled: true } } }; disabling sends only the off entry; a rejected fetch rolls the switch back and shows the error; a timer left by an earlier save does not clear a later save's error; the profile select PATCHes only the profile.tests/unit/ui/compressionPanelEnginesPartialWrite.test.tsx(3 cases): single-engine PUTs from the panel, two engines in turn, and a level change that carries the current switch state.Reviewer Notes
PUT { engines: {} }used to store an explicit all-off map; it now changes nothing, because nothing is merged over. No caller insrc/,open-sse/orbin/sends an empty or wholesale map; the MCP engine tool rebuilds the full map from a fresh read and is unaffected.