Skip to content

fix(ton-gram): break circular import in chain-slug alias layer - #711

Merged
Flotapponnier merged 1 commit into
mainfrom
fix/ton-gram-circular-import
Jun 25, 2026
Merged

fix(ton-gram): break circular import in chain-slug alias layer#711
Flotapponnier merged 1 commit into
mainfrom
fix/ton-gram-circular-import

Conversation

@Flotapponnier

Copy link
Copy Markdown
Collaborator

vercel --prod from clean main failed with TDZ 'Cannot access ec before initialization' in loadAllBenchmarks. Root cause: PR #708 added import { canonicalChainSlug } from '@/lib/chains' to spec.ts, but chains.ts imports @/data/benchmarks which imports @/lib/spec → cycle.

Fix: extract CHAIN_SLUG_ALIASES + canonicalChainSlug into a new src/lib/chain-aliases.ts with no data-layer imports. chains.ts re-exports them for UI consumers, spec.ts imports directly from chain-aliases. chainLabelForSlug stays in chains.ts (depends on CHAIN_BY_SLUG registry).

Verified locally with pnpm build — succeeds. Deploying to prod from this branch state now.

Build crashed on prod with 'Cannot access ec before initialization'
in loadAllBenchmarks because spec.ts → chains.ts → @/data/benchmarks
→ @/lib/spec is a cycle. The TDZ fires at ESM eval time when both
ends touch each other before exports settle.

Extract the alias map + canonicalChainSlug into a new
src/lib/chain-aliases.ts module that has no imports from the data
layer. chains.ts re-exports them for backwards compat with any UI
consumer, and spec.ts imports directly from chain-aliases to stay out
of the cycle. chainLabelForSlug stays in chains.ts because it depends
on CHAIN_BY_SLUG (the registry IS chains.ts).

Discovered by 'vercel --prod' from a clean main checkout. Repro:
- prebuild succeeds
- runtime page-data collection fails for /alternatives/[slug]/opengraph-image
- root cause: spec.ts evaluates before chains.ts finishes; canonicalChainSlug
  is undefined when overlayEditorial tries to call it.
@Flotapponnier
Flotapponnier merged commit 3a8f309 into main Jun 25, 2026
Flotapponnier added a commit that referenced this pull request Jun 25, 2026
Follow-up to #708 / #711. The alias system was added but only applied
to getBenchmarksForChain + ChainHeadingsSummary + overlayEditorial.
Every other place that did a strict-equality chain-slug match still
404'd or rendered wrong when called with the canonical slug ('gram')
while the YAML dimension / result row still held the legacy slug
('ton'). The user hit /benchmarks/wallet-labels-coverage/gram and got
a 404.

This PR pushes matchesChainSlug into every site that does a slug ===
match on a chain.

New helper in src/lib/chain-aliases.ts:
- matchesChainSlug(a, b) — both args optional, case-insensitive,
  resolves both sides through canonicalChainSlug. Replaces every
  '=== chain' on a chain-slug.
- chainSlugSiblings(slug) — returns the set { canonical, ...legacy }
  for use as a filter Set.

Patched 9 surfaces:
- src/app/benchmarks/[slug]/[chain]/page.tsx — perChainExplainer
  lookup, results.find (row shape), dimensions.find (dimension shape),
  region variant fetch. /benchmarks/wallet-labels-coverage/gram now
  resolves.
- src/app/api/badge/[slug]/[provider]/route.ts — chainLabel + cell
  param resolution. Badge endpoint accepts ?chain=gram.
- src/app/api/bench/[slug]/variant/route.ts — variant filter
  validation. ?chain=gram no longer returns 'unknown chain'.
- src/app/benchmarks/[slug]/share-card/route.tsx — OG share card
  chain pill resolution.
- src/components/benchmark-body.tsx — client-side initial tab
  selection from ?chain= URL param.
- src/app/chains/[slug]/page.tsx — per-bench dimension/result/route
  detection on the chain hub.
- src/app/benchmarks/[slug]/opengraph-image.tsx — chain label on OG
  image.
- src/app/benchmarks/[slug]/twitter-image.tsx — same for Twitter
  cards.
- src/app/sitemap.ts — emits canonical slug URLs (/gram) instead of
  legacy (/ton) so crawlers don't waste budget on 308s. Per-chain
  explainer filter uses canonical comparison.

What is NOT in this PR (deliberately):
- Schema change to dimensions (value/prom_value/aliases) — too much
  surface, deferred to a separate refactor once harness rotates.
- Harness Go code update (chain='ton' → 'gram' label) — separate
  Railway redeploy.
- middleware-level URL canonicalization — next.config.ts redirects
  already cover the legacy /ton URLs; middleware adds nothing right
  now.
@Flotapponnier
Flotapponnier deleted the fix/ton-gram-circular-import branch July 17, 2026 14:43
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