Repository navigation
feat(client-devtools): close the gap to the panel design - #102
Merged
Merged
Conversation
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.
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
Conventional Commits ValidationPR Title: valid |
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.
Contributor
Conventional Commits ValidationPR Title: valid |
|
|
||
| // JSON first so a number stays a number, falling back to the raw string | ||
| // for the common case of typing a word rather than a quoted one. | ||
| let parsed: unknown = value.value; |
This branch was successfully deployed
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.
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
pendonly appears when there issomething pending: a permanent
0 pendteaches you to stop reading it. Thering 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
offsetbeatsanything 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.
orderCreateinvalidatingOrder:{res.id}against alist carrying
Order[]is the case, and it is the defect this package existsto 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.