Repository navigation
Commit a4c5975
authored
feat(client-devtools): close the gap to the panel design (#102)
* feat(client-devtools): close the gap to the panel design
The last pass shipped the structural half and I called it finished, which it
was not. This is the rest of it, or nearly.
The launcher grew the two things it was drawn with. Vitals slide out on hover,
so the resting state is still one tile, and `pend` only appears when there is
something pending: a permanent `0 pend` teaches you to stop reading it. The
ring goes amber while the overlay stack is non-empty. A stuck optimistic write
is a bug you want to see and a request in flight is Tuesday, so pending
outranks fetching and a real error outranks both.
It also gets out of the way now. If a framework's dev badge already owns the
bottom-right corner the launcher lifts itself above it, which is the collision
that started this whole piece of work. Matched by element name rather than by
position, because measuring layout on mount is how a devtools panel starts
causing the reflows it exists to help you find. An explicit `offset` beats
anything it guessed.
The trace flags near misses now, and here is the threshold. Per raised tag, not
per cause. A tag that reached no query and closely resembles one somebody
carries gets a banner even when the same cause reached something through a
different tag, because the tag that missed is still wrong and the one that
landed is what hides it. `orderCreate` invalidating `Order:{res.id}` against a
list carrying `Order[]` is the case, and it is the defect this package exists
to explain. A tag that reached nothing and resembles nothing stays quiet.
The vitals strip is back to what StoreSnapshot actually holds. Tombstones and
stamped tags are both bounded caches, so a number that climbs is the shape of a
leak, and neither was visible anywhere.
Network rows draw a bar. Two segments and only two, wire and backoff, because
those are the two the transport measures. It does not report when a response
started decoding or when the store committed it, and a bar that split those out
would be drawing a shape nobody measured.
You can act on the overlay stack: roll a layer back, promote one by hand, and
read the base record beside what the fold makes of it, changed fields only.
Holding a query in loading or error is panel-local and writes nothing. The row
says held, the pane says held, the trace says you did it, and release is a map
delete. A faked state has to be impossible to mistake for a real one and
reversible without the cache unwinding anything.
Keyboard: escape, 1 to 9, cmd-shift-F, f for freeze, space, and r and i for the
selected row. Nothing fires while you are typing. A panel that eats a 3 out of
its own filter box is worse than one with no shortcuts.
Every query pane has a why button that opens Explain already pointed at it,
instead of asking you to type an exact key from memory into a filter box.
The panel opened on the queries tab while the tab list started with the trace.
A test caught it. It opens on the trace now.
Budgets re-baselined once rather than nudged a fourth time. The reasoning is in
the test: the panel is one closure over shared UI state and there is nothing a
consumer could decline to import, so splitting would cost more than it saves.
The parts that could be declined were split out already and they are
./requests and ./control.
Still missing, and deliberately: copy as curl and replay, which need headers
and a transport reference the request log does not keep on purpose; per-phase
timings, which need more transport events; a command palette, which duplicates
the filter box.
* feat(client-devtools): finish the panel design
The last of it. What is left out at the end is left out for a reason, not
because I ran out of road.
Editing an entity field pushes a patch onto the overlay stack. This is the
argument the whole state-manipulation section rested on and it was the one
piece of it I had not built. A devtools edit now rides the same machinery a
pending optimistic mutation does, so it never writes the base store, undo is
removing the entry rather than applying an inverse, and an evicting stream
frame takes it with it exactly as it would take a real optimistic write. A
merge over a base record that is gone patches nothing, and that rule was
already in OverlayStack.
RestTransport closes the credential refresh now. `refresh` had no matching
event, so a watcher could say a request hit the refresh but not how long it sat
there, which is the only number that tells an auth stall apart from a slow
server. The waterfall draws that wait in violet, beside the wire and the
backoff.
Force stale marks one query behind the server without asking for it again.
Invalidate raises its tags and reaches everything sharing them; this reaches
one, and leaves the request for whenever something next needs it. That is the
state you want when you are trying to see what a stale read looks like.
Curl on the request pane. The credential is a placeholder because the log never
keeps the real one, which is the reason it is cheap enough to leave running.
The shortcuts are finished: slash and cmd-K into the filter box, cmd-Z pops the
top overlay, F11 for fullscreen, enter explains the selected row. The mock drew
a command palette and it is a filter box instead, because that box already
parses status:4xx, >100ms and tag:, and a palette would be a second front door
to the same room.
Budgets: the inspection entry went to 6.5 kB and the combined one to 10 kB. The
action layer grew from six calls to eleven, and the panel needs all five of the
new ones.
Three things are still not here. Replay needs a transport reference the log
does not hold. Mocking a response needs the same. Queued, decode and commit
timings need boundaries nobody reports: they happen in the generated client and
in the cache, not in the transport, so drawing them would mean inventing a
shape nobody measured.1 parent a84dc2d commit a4c5975
12 files changed
Lines changed: 1908 additions & 20 deletions
File tree
- packages
- client-core
- __tests__
- src
- client-devtools
- __tests__
- src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
150 | 150 | | |
151 | 151 | | |
152 | 152 | | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
153 | 202 | | |
154 | 203 | | |
155 | 204 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
273 | 273 | | |
274 | 274 | | |
275 | 275 | | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
276 | 284 | | |
277 | 285 | | |
278 | 286 | | |
| |||
484 | 492 | | |
485 | 493 | | |
486 | 494 | | |
| 495 | + | |
487 | 496 | | |
| 497 | + | |
| 498 | + | |
488 | 499 | | |
489 | 500 | | |
490 | 501 | | |
| |||
0 commit comments