Skip to content

Strip brand and codec internals from the published declarations - #6202

Closed
candrewlee14 wants to merge 3 commits into
drizzle-team:rc5from
candrewlee14:strip-brand-and-codec-internals
Closed

Strip brand and codec internals from the published declarations#6202
candrewlee14 wants to merge 3 commits into
drizzle-team:rc5from
candrewlee14:strip-brand-and-codec-internals

Conversation

@candrewlee14

Copy link
Copy Markdown

Stacked on #6200 and #6201. Review only the last commit; the diff shrinks as the parents land.

What

Marks three implementation details /** @internal */ so stripInternal keeps them out of the published declarations:

  • Name#brand (protected)
  • Param#brand (protected)
  • CodecsCollection#resolveTypes (protected)

All three are pure internals — two are type-level brands that exist only to keep the classes distinct, and resolveTypes is a constructor-supplied resolver. None is callable by a consumer. But each was emitted into the .d.ts, making its class nominal and therefore non-portable between two installs.

On the codecs.ts shape change

resolveTypes moves from a constructor parameter property to a declared field. @internal on a parameter does strip the member, but the marker itself survives into the emitted constructor signature as a stray comment:

constructor( /** @internal */ resolveTypes: (type: string) => string, codecs?: Codecs<TTypeSet>);

Declaring the field puts the marker on the member and leaves the emitted signature clean. Runtime behaviour is identical — a parameter property assigns at the top of the constructor body, which is exactly where the explicit assignment now sits.

Result

Param, Name and CodecsCollection flip to portable: true in the matrix.

The three dialects do not follow, which is worth flagging: CodecsCollection#resolveTypes was their reported blocker, but with it gone they fail structurally instead, on BuildRelationalQueryResult['selection'] — an anonymous recursive intersection-of-union reached via mapperGenerators.relationalRows. Having no named symbol it misses the compiler's relation cache, so each cross-instance comparison re-expands until the recursion limiter gives up. That is a different class of problem and needs the type named rather than a member marked, so it is recorded as their blocker and left alone here.

Verification

test:types clean; full drizzle-orm suite green.

cursoragent and others added 3 commits August 29, 2026 11:44
Strip implementation-only query-builder details from published declarations, infer decoder results structurally, and compile two physical package copies to prevent regressions.
The single SQL assignment only guarded one type. Replace it with a table of
public types probed in one tsc program, asserting both directions: a portable
type regressing fails, and a known leak becoming portable fails too, prompting
the flag to be flipped.

Records the measured state of the surface, annotating each known leak with the
private/protected member responsible.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qd99Mmmi1fZkKQiV3u1jXy
Name#brand, Param#brand and CodecsCollection#resolveTypes are implementation
details that reached the emitted .d.ts as protected members, making all three
types nominal and so non-portable between two installs of the package.

resolveTypes is declared as a field rather than left as a constructor parameter
property: on a parameter the @internal marker survives into the emitted
constructor signature as a stray comment.

Flips Param, Name and CodecsCollection to portable in the matrix. The three
dialects do not follow -- with the nominal blocker gone they fail structurally
instead, on the anonymous recursive BuildRelationalQueryResult['selection'],
which is recorded as their blocker.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qd99Mmmi1fZkKQiV3u1jXy
@candrewlee14

Copy link
Copy Markdown
Author

Consolidated into #6200. The whole change is 244 lines across 16 files, and because a fork PR cannot base itself on another fork branch, every PR in the stack was already showing all of its ancestors' commits — so the split bought no review isolation, just six merges and five rebases. It is now one PR with these commits intact, plus #6205 for the single change that touches observable API.

@candrewlee14
candrewlee14 deleted the strip-brand-and-codec-internals branch August 29, 2026 19:02
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