Repository navigation
refactor: give duplicated helpers one home - #1089
Merged
lcottercertinia merged 5 commits intoSep 29, 2026
Merged
Conversation
SOQLView, DMLView and SOSLView each re-registered the Tabulator modules and re-declared the clipboard and grouping options that TableShared already owns. Route all three through registerTableModules, which gains a `grouping` flag, and the new groupingOptions const. BottomUpTable drops its own bare registerModule call for the same three grouping modules, and adopts clipboardCopyOptions and groupingOptions. groupToggleElement stays per table. A grid with a groupClick handler sets false; BottomUpTable has none and needs 'header'. GroupCalcs and GroupSort declare their table options through module augmentation, matching AnchoringPolicy. That retires two internal @ts-expect-error comments and the one in BottomUpTable. The three views now also get AnchoringPolicy. That is inert without `anchoringPolicy: true`, which none of them sets, so behaviour is unchanged and no CHANGELOG entry is due.
Ten hand-rolled ns-to-ms conversions and percent-of-whole calculations now call core/utility/Duration.ts and core/utility/Util.ts. That retires six unseparated 1000000 literals and four spellings of the divide-by-zero guard. formatMs becomes formatNsAsMs. It takes nanoseconds, so at a call site the old name read as a conversion that was not happening. No behaviour change. ProgressComponent's guard widens from `totalValue !== 0` to `whole > 0`; both its callers feed durations and row counts, so a negative never reaches it. StackedTimeBar's readout gains a zero guard it cannot use, since render() already returns early on `denominator <= 0`.
Three copies of the same pop-and-push depth-first loop become one walkEvents generator in core/utility/EventTree.ts, beside outermostEvents. A generator, so each caller keeps its own per-event work in its loop body — namespaceSelfTimes still checks its frame budget and still returns null when a walk is abandoned. Line count barely moves: the helper costs what the three loops saved. The point is one named walk with tests, instead of three hand-rolled stacks with none. Two sites the plan names are not in this commit: - optimised/apex-limit-series.ts:138 walks every event in the log to build the metric strip, with a hand-written indexed loop. Swapping in a generator there needs a measured before and after, and `pnpm measure` has no stage that calls apexLimitTimeSeries. - core/log/frameVariables.ts:1048 pushes children back to front on purpose, so popping yields them in log order. walkEvents would have to offer that ordering first.
Ten sites wrote `x instanceof Error ? x.message : String(x)` by hand. tryCatch.ts already had that normalisation, private; it is now exported alongside errorMessage, which is the `.message` all ten wanted. No behaviour change: errorMessage gives the same string either way, since new Error(String(x)).message is String(x). log-viewer's two sites stay as they are. It must not import from lana.
…icated-code # Conflicts: # log-viewer/src/features/timeline/utils/category-self-time.ts
lcottercertinia
approved these changes
Sep 29, 2026
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.
📝 PR Overview
Four small pieces of duplicated logic get one home each. Nothing a user can reach
changes. Every commit was checked against the code it replaced rather than assumed
equivalent — three of the plan's own predictions turned out to be wrong, and are
recorded below.
🛠️ Changes made
use TableShared in the database grids— SOQL, DML and SOSL each re-registeredthe Tabulator modules and re-declared the clipboard and grouping options that
TableSharedalready owns.registerTableModulesgains agroupingflag, andgroupingOptionsis new.GroupCalcsandGroupSortnow declare their tableoptions by module augmentation, matching
AnchoringPolicy; that retires three@ts-expect-errorcomments.route duration and share maths through the helpers— ten hand-rolled ns-to-msconversions and percent-of-whole calculations now call
core/utility/Duration.tsand
core/utility/Util.ts. Six unseparated1000000literals and four spellings ofthe divide-by-zero guard go with them.
formatMsbecomesformatNsAsMs: it takesnanoseconds, so at a call site the old name read as a conversion that was not
happening.
walk event trees through one generator— three copies of the same pop-and-pushdepth-first loop become
walkEventsincore/utility/EventTree.ts, besideoutermostEvents. A generator, so each caller keeps its own per-event work in itsloop body:
namespaceSelfTimesstill checks its frame budget and still returnsnullwhen a walk is abandoned.export toError and use it— ten sites inlana/wrotex instanceof Error ? x.message : String(x)by hand.tryCatch.tsalready had thatnormalisation, private. It is now exported alongside
errorMessage.Three things that look like behaviour changes and are not
AnchoringPolicy. It is inert withoutanchoringPolicy: true, which none of them sets:AnchoringPolicy.ts:67registersthe option defaulting to
false, and:70-78gates every listener on it.ProgressComponent's guard widens fromtotalValue !== 0towhole > 0. Bothcallers feed durations and row counts, so a negative never reaches it.
errorMessagereturns the same string either way, sincenew Error(String(x)).messageisString(x).log-viewer's own two error-normalisation sites stay hand-rolled. It must not importfrom
lana/.Left out on purpose
optimised/apex-limit-series.tswalks every event in the log through a hand-writtenindexed loop. Swapping in a generator there needs a measured before and after, and
pnpm measurehas no stage that callsapexLimitTimeSeries.core/log/frameVariables.tspushes children back to front on purpose, so poppingyields them in log order.
walkEventswould have to offer that ordering first.categorySelfTimesfunctions are not duplicates, despite looking it. Onestarts at
root.childrenand the other atroot; one buckets uncategorised eventsinto
OTHER_CATEGORYand the other drops them; one keys bystringand is memoised,the other keys by
LogCategoryand is not. Deleting either changes what the UIshows.
🧩 Type of change (check all applicable)
📷 Screenshots / gifs / video [optional]
None — no UI change.
🔗 Related Issues
None.
✅ Tests added?
log-viewer/src/core/utility/__tests__/EventTree.test.tsis new: 7 cases forwalkEvents, including a 100,000-deep chain and early termination by the caller.The full gate ran on every commit —
pnpm exec tsc -b --force,pnpm exec eslint,pnpm test. 2,632 tests across 192 suites, green.📚 Docs updated?
No CHANGELOG entry: nothing here is reachable by a user. The plan that produced this
work predicted one commit would close an
AnchoringPolicygap in the database gridsand so need an entry. It does not — see above.
Anything else we need to know? [optional]
Not checked in the dev host. Worth one pass on the SOQL, DML and SOSL tabs before
merge: grouping still groups, group headers still show calcs when a group is closed,
Cmd/Ctrl+Ccopies the whole table, CSV download works. Tabulator's module registry isbarely exercised under jsdom. The percentage and duration readings in those grids, in
StackedTimeBar, in theGovernorSummarygauges and in the database overview are theother thing to glance at.
Independent of #1066 and #1069 — no file overlap, so these can merge in any order.