Skip to content

fix(web): wire API reachability, lenient string search params, sidebar state, chart and cache memoization - #2445

Merged
Makisuo merged 18 commits into
perf/audit-backend-servicesfrom
fix/audit-frontend-fixes
Nov 10, 2026
Merged

Makisuo merged 18 commits into
perf/audit-backend-servicesfrom
fix/audit-frontend-fixes

Conversation

@Makisuo

@Makisuo Makisuo commented Nov 10, 2026 •

Copy link
Copy Markdown
Collaborator

Stacked on #2444. Part of the audit stack that starts at #2434.

Bugs fixed

  • A dropped connection was reported as a query error. WarehouseUnreachableError could never be raised: nothing provided ApiReachability after the React app was deleted, and nothing read the reachability clock the HTTP client wrote. The client now marks an origin unreachable on any transport failure and reachable on any response, and the warehouse layer reads that clock.
  • A hand-written link with an unquoted value landed on NotFound. Search values are JSON-parsed, so /logs?search=404 or /replays?userId=12345 arrived as a number, a string schema rejected it and the route fell through. String params now accept a number, boolean or null and print it back as text. A number that does not print back as written (20 digits, 1e5) stays text, so a long numeric id is not rounded.
  • A collapsed sidebar reopened on every reload. The sidebar_state cookie was written on each toggle and never read. It is read at boot now. Visible change: anyone who last collapsed the sidebar will find it collapsed after this ships.
  • The boot Flags schema lacked shell.platform, which the flags reader returns. It only worked because fresh flags are not decoded.

Efficiency

  • Bar charts with more than 12 series re-bucketed and re-encoded on every hover. bucketBarSeries returned a fresh array per render, so both spec caches, keyed on array identity, missed. It and seriesDefinitionsOf are now memoized per rows array.
  • Maple Local's query cache leaked. Use times were never pruned and the whole map was copied on every lookup. Relative time ranges mint new keys continuously, so a tab left open grew without bound. Use times are pruned with their entries.

Cleanup

  • route/search.ts redeclared five constants that two other modules already export. It imports them now. 44 comments describing a router this app no longer uses are gone.

Verification

  • apps/web: 29 test files, 237 tests, plus 29 route tests after the last cases were added. packages/views charts: 37. apps/local-ui data: 12. packages/web-data: 25. All pass.
  • Confirmed failing on the old code: the two reachability tests, the collapsed-sidebar test and the Flags test. The route, chart and cache tests were not run against the old code.
  • Typecheck is clean for apps/web, apps/local-ui and packages/views. Lint and format are clean.
  • Nothing was run in a browser. The preview of this stack is where the sidebar cookie and a hand-written link get checked.

Known gaps

  • ?tab=bogus and other strict literal params still land on NotFound. That needs a fallback helper on about 50 fields.
  • A number param written as 1.0 no longer decodes, because it does not print back as written.
  • The Electric long-poll client does not feed the reachability clock.

Autofix with [code]smith
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.

…r cookie, boot flags

- Reachability: the client's request wrapper now starts the origin's failure
  run on any transport failure (the 45 s deadline included) and ends it on any
  response, and the warehouse layer provides ApiReachability from that clock.
  Nothing provided it before, so a dropped connection inside the 15 s grace
  window was reported as a WarehouseQueryError instead of
  WarehouseUnreachableError.
- Search params: string params decode through one lenient codec, so a link
  written by hand with an unquoted number, boolean or null (?userId=12345,
  ?search=404, ?q=true) opens the page instead of NotFound. String arrays take
  the same values. It replaces the one-off DigitsParam on the Cloud SQL peek.
  The search parser keeps a number that does not print back as written (past
  2^53, exponent form) as text, so a long numeric id is not rounded.
- Sidebar: the sidebar_state cookie written on every toggle is read with the
  other boot flags, so a collapsed sidebar stays collapsed after a reload.
- Flags: the schema carries shell.platform and shell.isSidebarOpen, which a
  decode of the flags used to strip.
- search.ts imports the dashboard variable prefix and the errors hub
  vocabulary from their owners instead of redeclaring them, and drops comments
  describing a router this app no longer uses.
…query cache's use-time leak

- Charts: bucketBarSeries and seriesDefinitionsOf keep their answer per rows
  array. Past 12 series the bar chart returned a fresh array on every render,
  so the spec cache and the encoding cache (both keyed on array identity)
  missed on every hover tick: all rows were folded again and the whole spec
  encoded to JSON again.
- Maple Local: collecting the query cache now drops the use times of the
  entries it drops. Relative ranges mint a new key per window, so the use-time
  map of a tab left open grew without bound and was copied on every lookup.
  The entries and their use times live in one ref, so they change together.
@coderabbitai

coderabbitai Bot commented Nov 10, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 1 minute.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: e857082a-438c-4ebb-ba31-ca9688927afc
Commits

Reviewing files that changed from the base of the PR and between 0d1d10a and 7f3f5b0.

Files selected for processing: 19

  • apps/local-ui/src/data/query-cache.test.ts
  • apps/local-ui/src/data/query-cache.ts
  • apps/web/src/data/warehouse.ts
  • apps/web/src/lib/services/common/http-client.test.ts
  • apps/web/src/lib/services/common/http-client.ts
  • apps/web/src/main.test.ts
  • apps/web/src/main.ts
  • apps/web/src/route/route.test.ts
  • apps/web/src/route/search.ts
  • apps/web/src/route/tanstack-search.ts
  • apps/web/src/shell/command.ts
  • apps/web/src/shell/flags.test.ts
  • apps/web/src/shell/flags.ts
  • apps/web/src/shell/index.ts
  • apps/web/src/shell/model.ts
  • packages/views/src/charts/bar-chart.test.ts
  • packages/views/src/charts/bar-chart.ts
  • packages/views/src/charts/chart-spec.ts
  • packages/views/src/charts/timeseries.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@maple-review-bot

This comment has been minimized.

@Makisuo
Makisuo added this pull request to stack #2450 November 10, 2026 03:23
@maple-review-bot

This comment has been minimized.

@maple-review-bot

This comment has been minimized.

@maple-review-bot

This comment has been minimized.

@maple-review-bot

This comment has been minimized.

@maple-review-bot

This comment has been minimized.

@maple-review-bot

This comment has been minimized.

@maple-review-bot

This comment has been minimized.

@maple-review-bot

This comment has been minimized.

@maple-review-bot

This comment has been minimized.

@Makisuo

Makisuo commented Nov 10, 2026

Copy link
Copy Markdown
Collaborator Author

On the review's one caveat (reachability is keyed on originOf(request.url), which must match originOf(apiBaseUrl)): the two agree whether or not the request URL is absolute. originOf in packages/web-data/src/lib/peer-reachability.ts parses with new URL(url, location.href), so a relative /_api/... request and the absolute same-origin apiBaseUrl both resolve to the page's origin, and an absolute request URL resolves to its own.

Still to check by hand in a signed-in preview session, as the review lists: a collapsed sidebar staying collapsed after a reload, and /logs?search=404 resolving to the Logs page.

@maple-review-bot

This comment has been minimized.

@maple-review-bot

This comment has been minimized.

@maple-review-bot

maple-review-bot Bot commented Nov 10, 2026 •

Copy link
Copy Markdown

Maple review

🟢 Confidence 10/10 · safe to merge. Mechanical, well-tested changes: each new behavior has a test and the cache memoization is a pure function of the rows array.
no findings · tests covered · risk medium

Wires the API reachability clock the HTTP client writes into the warehouse layer, makes string search params accept an unquoted number/boolean/null, reads the sidebar cookie at boot, and memoizes bar-chart rows and cache use times. Safe to merge.

  • withRequestTimeout marks an origin reachable on any response, unreachable on transport failures
  • StringParam accepts number, boolean and null and prints them back as text
  • shell.flags reads sidebar_state so a collapsed sidebar stays collapsed
  • rowsCache and collectUnused keep chart rows and prune cache use times

Before merge

  • Manual · Check the collapsed sidebar and a hand-written ?userId=12345 link in the preview:web deploy; nothing was run in a browser

7f3f5b0 · What was checked, coverage and telemetry details are on the Maple / review check. Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.

@Makisuo
Makisuo merged commit fb4441a into main Nov 10, 2026
31 checks passed
@maple-review-bot

Copy link
Copy Markdown

Merged with 1 step from "Before merge" still open. If it is done, tick it on the review comment; if not, now is the time.

  • Manual · Check the collapsed sidebar and a hand-written ?userId=12345 link in the preview:web deploy; nothing was run in a browser

@Makisuo
Makisuo deleted the fix/audit-frontend-fixes branch November 10, 2026 11:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant