Repository navigation
feat(thermidor): lock surfaces while a request is in flight instead of queuing gestures (PoC) - #8709
fbeaudoincoveo wants to merge 2 commits into
Conversation
…PoC) Disables the active turn's controls from the moment a state-changing action or follow-up is sent until its stream closes, instead of queuing gestures. The dimming waits 150 ms so fast answers never flash, focus returns to the control that was used, and facet search typing never locks. A toggle in the corner (or `?lockSurfaces=off`) switches the lock off for comparison. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dundant (PoC) With the active surface disabled while a request is in flight, at most one gesture is outstanding at a time, so the machinery built to queue several has nothing left to do: - @coveo/thermidor: the dispatch coordinator and tracker (coalescing, dispatch ids and outcomes), `Session.actions`, the optimistic value controller, and stale scopes. The session keeps a plain promise chain so an action sent alongside a lookup still goes out in order. - demo-schema-react: `pending-dispatch`, every `coalesce`/`invalidates` declaration, the numeric facet's landing-value logic, and the trace helper. An optimistic value now holds until the next request ends, and the results dim while an action is in flight. Facet search is debounced instead of superseding queued searches. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
commit: |
|
Tip All tests passed and all changes approved!🟢 UI Tests: 439 tests unchanged |
Jira
None. This is a proof of concept to show the experience and the code it removes. It isn't meant to merge as is.
Motivation
Thermidor lets the shopper keep clicking while an action is in flight: it queues the gestures, coalesces them, and holds optimistic values across several outstanding requests. The Agent Gateway accepts one turn per session anyway, and a facet action is a Commerce API round trip, not an agent turn. So the wait is short and the queue mostly hides it.
This PoC tries the simpler model: disable the active surface while a state-changing request is in flight, so at most one gesture is ever outstanding. Then it removes the code that model makes redundant.
Changes
1. Lock the surface while a request is in flight (
demo-schema-react)fieldsetis disabled from the moment an action or follow-up is sent until its stream closes.?lockSurfaces=off, turns the lock off for comparison.2. Drop what the lock makes redundant (
@coveo/thermidor,demo-schema-react), 3.3k lines@coveo/thermidor: the dispatch coordinator and tracker (coalescing, dispatch ids and outcomes),Session.actions, the optimistic value controller, and stale scopes. The session keeps a plain promise chain, so an action sent alongside a lookup still goes out in order. The409retry from feat(thermidor): retry Agent Gateway 409 AGENT:ACTION_IN_FLIGHT rejections j:KIT-6296 #8665 now runs on that chain.demo-schema-react:pending-dispatch, everycoalesceandinvalidatesdeclaration, and the numeric facet's landing-value logic.useOptimisticValuenow holds a value until the next request ends. The results dim while an action is in flight. Facet search is debounced (200 ms) instead of superseding queued searches.docs/architecture.mddescribe "one action at a time" instead of the queue.Known trade-off: with the lock off, a second click during a request is dropped and its checkmark reverts when the first request ends. The toggle compares the lock with no protection at all, not with the old queue.
Validation
@coveo/thermidor: typecheck, unit tests andtest:dtspass. The409session tests now go throughdispatchAction.demo-schema-react: typecheck and unit tests pass. Each commit was checked on its own. Tests that only covered coalescing were removed. The sixenv.test.tsfailures fail the same way onmain; they come from a local.env.Checklist
feat(<scope>): <description>)@coveo/thermidorand the sample are private🤖 Generated with Claude Code