Skip to content

build: depend on @apexdevtools/apex-log-parser - #1068

Open
lukecotter wants to merge 2 commits into
certinia:mainfrom
lukecotter:feat-adopt-apex-log-parser
Open

lukecotter wants to merge 2 commits into
certinia:mainfrom
lukecotter:feat-adopt-apex-log-parser

Conversation

@lukecotter

@lukecotter lukecotter commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator

📝 PR Overview

The parser now ships as @apexdevtools/apex-log-parser,
released from apex-dev-tools/apex-log-parser.
This deletes the in-repo copy and depends on 0.1.1, so one parser serves every consumer and its
fixes arrive by version bump.

Adoption only — no behaviour change, and no new parser capability is used yet. The published API
had moved on from the local copy, so absorbing that drift is most of the diff.

🛠️ Changes made

  • Delete apex-log-parser/ and depend on @apexdevtools/apex-log-parser@0.1.1 from lana/,
    log-viewer/ and the root (scripts/measure resolves from there).
  • Re-point 122 import sites. The package splits its surface: runtime on the root export, types and
    consts on /types.
  • GovernorLimits no longer carries the metrics flat, so reads move under final, and heapSize
    under peak to mirror what the old flat field meant. Every one takes the ceiling and nothing
    reads used. See the correction below on what this does and does not preserve.
  • ApexLog.debugLevels is a record now, so LogLevels maps its keys back to the log's own tokens
    and the chips read as before.
  • Drop the hand-rolled resolution this needed: a tsconfig project reference and paths in three
    configs, a jest project and two moduleNameMapper entries, a rolldown alias, four
    allowDefaultProject entries, and the CI matrix entry.
  • Jest maps the package to its files. It is ESM-only and publishes no require condition, which is
    what jest's CJS runtime asks for; widening the export conditions instead pulls every other
    dependency's ESM build in with it. The jsdom setup lends the parser a TextEncoder.
  • Second commit: limitValue stood in three places after the swap — logOverviewMetrics exports
    it now and both production and the test helper call it.

🧩 Type of change (check all applicable)

  • 🐛 Bug fix - something not working as expected
  • ✨ New feature – adds new functionality
  • ♻️ Refactor - internal changes with no user impact
  • ⚡ Performance Improvement
  • 📝 Documentation - README or documentation site changes
  • 🔧 Chore - dev tooling, CI, config
  • 💥 Breaking change

📷 Screenshots / gifs / video [optional]

None — nothing user-visible changes.

🔗 Related Issues

None.

✅ Tests added?

  • 👍 yes
  • 🙅 no, not needed
  • 🙋 no, I need help

No behaviour changes, so no new tests. The parser's own four test files leave with it; all four
exist upstream in src/__tests__/, alongside six more. The suites that cover the consumers all
still run: 2479 tests across 184 suites.

📚 Docs updated?

  • 🔖 README.md
  • 🔖 CHANGELOG.md
  • 📖 help site
  • 🧪 Marked any pre-release-only features
  • 🙅 not needed

No user-visible change, so no CHANGELOG entry. AGENTS.md and .claude/rules/log-viewer.md are
updated, since both described the deleted package.

Anything else we need to know? [optional]

Verified: pnpm lint clean · 2479 tests in 184 suites · pnpm build emits all three bundles ·
pnpm run measure parses a 19MB log in 260ms · pnpm run ci:install validates the lockfile from an
empty node_modules.

Lockfile churn is larger than the change. Only @apexdevtools/apex-log-parser@0.1.1 is a real
addition; the rest is pnpm 10.34.5 rewriting peer-dependency hashes against a lockfile written by an
older pnpm. lockfileVersion is unchanged and --frozen-lockfile passes, so anyone's next install
would produce the same.

Two things seen in passing, not fixed here. Timeline.ts divides SOSL rows by the SOSL query
limit — eventText.ts and database/limits.ts both do it correctly. And the version is pinned in
three manifests with no pnpm catalog, so bumping two of the three would leave scripts/measure
benchmarking a different parser than the extension ships, silently.

Correction to an earlier claim in this PR. It previously said the reshape moves no displayed
number, because "the parser folds the same snapshots into both sides with Math.max, so the two
state the same ceiling". Both halves are wrong, verified against the published parser:

  1. final.X.limit === peak.X.limit is not an invariant. byNamespace takes each namespace's
    last snapshot as its final with no max-fold, while peak accumulates the highest ceiling
    seen. A LIMIT_USAGE_FOR_NS block cut short by truncation makes them diverge — reproduced with
    a truncated second block:

    dmlStatements  final {used:0, limit:0}  peak {used:1, limit:150}
    cpuTime        final {used:0, limit:0}  peak {used:100, limit:10000}
    heapSize       final {used:0, limit:0}  peak {used:0, limit:6000000}
    

    On such a log Heap keeps a denominator while SOQL/DML/CPU lose theirs. Not a regression — main
    also took the last block's value and showed 0 for all four — but the stated reason was wrong,
    and it matters if anything later moves a read between final and peak.

  2. One displayed number does move. The old ceiling was the last namespace in iteration order;
    the new one is Math.max across namespaces. On a log where a managed package has a higher
    ceiling than (default), the Heap denominator changes. Reproduced: (default) 6000000 plus
    (mypkg) 12000000 now yields 12000000 in either block order, where the old value depended on
    which came last. The new value is at least order-independent, but it is still the wrong ceiling
    for default-namespace rows — the known ✨ feat(database): per-namespace governor limits / overall limit view (certified managed packages) #862, whose explanatory comment left with the deleted
    file.

Nothing reads .used off a GovernorLimits anywhere in log-viewer/src or scripts, which was
checked by grep over every read site and is the part of the original claim that holds.

scripts/measure now benchmarks the published parser, not parser source — the rolldown alias
that pointed at apex-log-parser/src is gone. Parse numbers either side of this PR are not
strictly comparable, and a parser-side change can no longer be measured locally without publishing.

Known upstream behaviour change. The published parser validates debug categories against a fixed
map and reports an unknown one through parsingErrors, which we surface as a notification. When
Salesforce adds a category, a log that opens cleanly today will lose that chip and show an error.
Raised upstream.

Delete the in-repo apex-log-parser and depend on the published package. Runtime
comes from the root export, types and consts from the /types subpath.

GovernorLimits no longer carries the metrics flat, so the reads move under
final, and heapSize under peak to mirror what the old flat field meant. Every
one of them takes the ceiling, and nothing reads used. The parser folds the same
snapshots into both sides with Math.max, so the two state the same ceiling and
no displayed number moves.

ApexLog.debugLevels is a record now, so LogLevels carries the key-to-token map
the parser keeps private and the chips read as before.

Jest maps the package to its files: it is ESM-only and publishes no require
condition, and widening the export conditions pulls every other dependency's
ESM build in with it. The jsdom setup lends the parser a TextEncoder.
limitValue stood in three places after the parser swap. logOverviewMetrics
exports it now, and limitTotals and the test helper both call it.

governorLimits takes peak as a second argument, defaulting to final, so a test
that needs them to differ is not locked out of the helper.

AGENTS.md pointed at a pnpm link:parser script that does not exist yet.

Two doc comments had ended up above the wrong declaration.
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.

2 participants