Skip to content

Refactor API Reference into a language provider registry - #1724

Merged
David Pine (IEvangelist) merged 2 commits into
release/13.6from
ievangelist-api-reference-language-factory
Sep 23, 2026
Merged

David Pine (IEvangelist) merged 2 commits into
release/13.6from
ievangelist-api-reference-language-factory

Conversation

@IEvangelist

Copy link
Copy Markdown
Member

Follow-up to #1588.

Problem

After #1588 merged, the C#/TypeScript pair was baked into every layer of the API Reference feature:

  • The resolution shape hardcoded csharp and typescript fields.
  • api-reference-core.ts mixed C#-specific document parsing, TS-specific route indexing, and cross-language linking in one ~965-line file.
  • ApiReference.astro had two ternary JSX blocks, one per language.
  • Diagnostic codes and CSS both hardcoded the language pair.

Adding a future AppHost language (Python, etc.) would have meant editing every one of those layers.

Refactor

Split the resolver into a small factory / provider registry:

  • src/utils/api-reference/language-provider.ts — ApiLanguageProvider, PrimaryLanguageProvider, TargetLanguageProvider, ExportMapping, PrimaryResolutionContext contracts.
  • csharp-provider.ts — Owns C# document parsing, candidate indexing, overload matching, export mapping (with pre-expanded receiver type FQNs), and C# target construction.
  • typescript-provider.ts — Owns TS route indexing and mapping resolution purely from cross-language ExportMapping data. No C# candidate details leak in.
  • registry.ts — Composes one primary provider + N target providers, drives resolution generically, and produces ApiReferenceResolution.targets keyed by provider id.
  • api-reference-core.ts — Shrinks to shared public types plus a slim buildApiReferenceIndex() that wires the default C# primary + TS target registry.
  • ApiReference.astro — Iterates over resolution.targets instead of duplicating two ternary render blocks. CSS switches to per-language data-lang rules.

Adding a new language now

  1. Implement one TargetLanguageProvider.
  2. Register it in the default registry in buildApiReferenceIndex.
  3. Add one CSS rule and one entry in the component's languages array.

No core-file edits required.

Preservation

  • Public API of api-reference.ts and api-reference-core.ts unchanged.
  • All diagnostic codes and message wording preserved verbatim.
  • resolution.csharp and resolution.typescript still populated (aliases of resolution.targets.csharp / .typescript) for source compatibility.
  • Same asymptotic cost: each provider's index is built once; .resolve() is O(1) per language.
  • All 820 unit tests pass unchanged.

Notes

The C#/TypeScript pair was baked into the resolution shape, the astro
component, and diagnostic codes. Adding a new AppHost language would
have meant editing every layer.

Split the resolver into a small factory:

* src/utils/api-reference/language-provider.ts defines the
  ApiLanguageProvider, PrimaryLanguageProvider, TargetLanguageProvider,
  ExportMapping, and PrimaryResolutionContext contracts.
* csharp-provider.ts owns C# document parsing, candidate indexing,
  overload matching, export mapping (with pre-expanded receiver type
  FQNs), and C# target construction.
* typescript-provider.ts owns TS route indexing and mapping resolution
  purely from cross-language ExportMapping data — no C# candidate leaks.
* registry.ts composes one primary provider plus N target providers,
  drives resolution generically, and produces
  ApiReferenceResolution.targets keyed by provider id.
* api-reference-core.ts shrinks to shared public types plus a slim
  buildApiReferenceIndex() that wires the default C# primary + TS
  target registry. Public API and diagnostic codes are unchanged.
* ApiReference.astro iterates over resolution.targets instead of
  duplicating two ternary render blocks. CSS switches to per-language
  data-lang rules that scale to future languages.

Adding, say, a Python target now means: implement one
TargetLanguageProvider, register it in the default registry, add one
CSS rule, and add one entry to the astro component's language list. No
core-file edits.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings September 23, 2026 13:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

One or more issues must be addressed before approval.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 Medium severity · 1 Low severity

Open (2)
What changed in this PR

Refactors API Reference resolution into a language-provider registry while preserving existing C#/TypeScript compatibility.

Changes:

  • Adds provider contracts and C#/TypeScript implementations.
  • Moves resolution orchestration into a generic registry.
  • Simplifies component rendering through language iteration and per-language CSS.
File Description
src/​frontend/​src/​utils/​api-reference/​typescript-provider.ts Updated as part of this pull request.
src/​frontend/​src/​utils/​api-reference/​registry.ts Updated as part of this pull request.
src/​frontend/​src/​utils/​api-reference/​language-provider.ts Updated as part of this pull request.
src/​frontend/​src/​utils/​api-reference/​csharp-provider.ts Updated as part of this pull request.
src/​frontend/​src/​utils/​api-reference-core.ts Updated as part of this pull request.
src/​frontend/​src/​components/​ApiReference.astro Updated as part of this pull request.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/frontend/src/utils/api-reference/typescript-provider.ts Outdated
Comment thread src/frontend/src/utils/api-reference/registry.ts
@aspire-repo-bot

Copy link
Copy Markdown
Contributor

Frontend HTML artifact ready

The latest frontend build uploaded the frontend-dist artifact for PR #1724. Use the VS Code button below to open this PR with GitHub Artifacts Explorer and browse the built HTML locally.

VS Code: Open PR #1724 artifacts

This comment updates automatically when a new frontend build artifact is uploaded.

* Carry the primary member's canonical language-neutral name through
  the PrimaryResolutionContext instead of taking the first mapping's
  MethodName. When a member declares multiple [AspireExport] attributes
  with different MethodName overrides (e.g. addWidget0/addWidget1) the
  method-group reference now falls back to picking a preferred route
  only if one actually matches the natural member name; otherwise it
  keeps every route and the resolver flags ambiguity.
* Add tests covering the registry contract:
  - method-group ambiguity when multiple MethodName exports exist,
  - resolution.targets is populated by the registry (not just the
    legacy csharp/typescript aliases),
  - a target-owned diagnostic flows through the registry,
  - a third, non-legacy 'python' target provider participates in
    resolution, index building, mapping consumption, target output,
    and diagnostics — verifying the abstraction end to end.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@IEvangelist
David Pine (IEvangelist) force-pushed the ievangelist-api-reference-language-factory branch from 6337cc7 to e5489c1 Compare September 23, 2026 15:07
@IEvangelist
David Pine (IEvangelist) merged commit f819b1c into release/13.6 Sep 23, 2026
2 checks passed
@IEvangelist
David Pine (IEvangelist) deleted the ievangelist-api-reference-language-factory branch September 23, 2026 15:08
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