Summary
csstype Property.* / Globals value-unions (Color, BackgroundColor, the
-moz-initial | inherit | initial | revert | unset … globals, the full 148 CSS
color keywords, etc.) are enumerated into giant @unboxed variants instead
of collapsing to the precise string mapping the extractor already knows how to
apply (isCssType, extract.mjs:1092). This fires when the csstype value is
reached through blend 0.0.38-beta.1's new ComponentTokenOverrides = DeepPartial<ComponentTokenType> wrapper — the same trigger as #205, but a
different symptom on a different code path.
Bindgen held constant, only the blend version bumped 0.0.38-beta.0 → 0.0.38-beta.1:
- 872 emitted identifiers ≥ 200 chars in
ContextSharedTypes.res alone (beta.0: 0); longest emitted line ≈ 12,071 chars.
- ~3,076 CSS-keyword constructor lines (
@as("aliceblue") Aliceblue, @as("-moz-initial") MozInitial, @as("currentcolor") Currentcolor …) added.
- The collision report's "left as-is" ambiguous constructors jump 162 → 397 — CSS keywords (
Aliceblue, AccentColor, Beige, Blueviolet … +241 more) now leak into the shared/collision namespace of ContextSharedTypes.
- The disambiguation table degrades from readable names (
CenterConfigAlign, LeftConfigSide) to monstrosities like CenterMozInitialOrInherit…OrCurrentColorOrContextComponentTokensTAGSSmMinWidthConfig.
Not the same as the already-filed issues
TS input → current output → expected output
TypeScript (via DeepPartial<ComponentTokenType>):
// a token leaf whose type is a csstype property union
minWidth?: Property.MinWidth<string | number> // = "-moz-initial" | "inherit" | … | (string & {}) | number | …
Current ReScript output (beta.1):
@unboxed type centerMozInitialOrInherit…OrCurrentColorOrContextComponentTokensTAGSSmMinWidthConfig =
| @as("-moz-initial") MozInitial
| @as("inherit") Inherit
| @as("aliceblue") Aliceblue
| … /* ~150 CSS keyword constructors */
| Currentcolor
| ContextComponentTokensTAGSSmMinWidthConfig
Expected (what isCssType already produces for a directly-referenced csstype value):
minWidth: string, // csstype Property.* → string (precise, not a loose fallback)
Suspected root cause
isCssType (extract.mjs:1092-1099) recognises csstype only by the
declaration's source-file path (/csstype/):
const sym = type.aliasSymbol || (type.getSymbol && type.getSymbol()) || type.symbol
const decl = sym && sym.getDeclarations && sym.getDeclarations()[0]
const file = decl && decl.getSourceFile().fileName
return !!(file && /[\\/]csstype[\\/]/.test(file))
When the value is reached through the homomorphic mapped type
DeepPartial<ComponentTokenType>, the checker hands back a synthesized /
apparent union of string-literal + globals types whose aliasSymbol /
declaration provenance no longer points at the csstype package file — so
isCssType returns false, the csstype→string shortcut is skipped, and the
union falls through to full member enumeration (→ #200's name bloat, cosmetically
capped by #201, plus the constructor leakage this issue is about).
Directly-referenced csstype values (not wrapped) still collapse to string
correctly — which is why beta.0 had 0 of these and beta.1 has 872.
Fix direction
Make csstype detection structural, not purely path-based, so it survives
mapped-type wrapping — e.g. recognise a union that is dominated by the csstype
Globals set (-moz-initial | inherit | initial | revert | revert-layer | unset)
and/or the CSS named-color vocabulary, optionally with a (string & {}) open arm,
and map it to string. Alternatively, unwrap DeepPartial<> / homomorphic
mapped types back to the source property type before classifying, so the original
aliasSymbol (and its csstype declaration file) is still visible to isCssType.
Collapsing at the source removes the 872 giant bodies entirely (not just their
names), stops the CSS-keyword constructor leakage into ContextSharedTypes, and
should also shrink the type graph enough to relieve part of #205.
Repro
npx @juspay/rescript-bindgen --pkg @juspay/blend-design-system@0.0.38-beta.0 --out /tmp/b0 --webapi --report
npx @juspay/rescript-bindgen --pkg @juspay/blend-design-system@0.0.38-beta.1 --out /tmp/b1 --webapi --report
# ≥200-char identifiers: 0 in b0, ~872 in b1 (ContextSharedTypes.res)
grep -oE '[A-Za-z0-9_]{200,}' /tmp/b1/ContextSharedTypes.res | wc -l
grep -oE '[A-Za-z0-9_]{200,}' /tmp/b0/*.res | wc -l
blend 0.0.38-beta.1 is already pinned in the benchmark, so this reproduces
in-repo. First observed in the downstream regen
blend-rescript#147, which
was generated against the last published bindgen (1.4.0-beta.1, pre-#201).
Summary
csstype
Property.*/Globalsvalue-unions (Color,BackgroundColor, the-moz-initial | inherit | initial | revert | unset …globals, the full 148 CSScolor keywords, etc.) are enumerated into giant
@unboxedvariants insteadof collapsing to the precise
stringmapping the extractor already knows how toapply (
isCssType,extract.mjs:1092). This fires when the csstype value isreached through blend
0.0.38-beta.1's newComponentTokenOverrides = DeepPartial<ComponentTokenType>wrapper — the same trigger as #205, but adifferent symptom on a different code path.
Bindgen held constant, only the blend version bumped
0.0.38-beta.0 → 0.0.38-beta.1:ContextSharedTypes.resalone (beta.0: 0); longest emitted line ≈ 12,071 chars.@as("aliceblue") Aliceblue,@as("-moz-initial") MozInitial,@as("currentcolor") Currentcolor…) added.Aliceblue,AccentColor,Beige,Blueviolet…+241 more) now leak into the shared/collision namespace ofContextSharedTypes.CenterConfigAlign,LeftConfigSide) to monstrosities likeCenterMozInitialOrInherit…OrCurrentColorOrContextComponentTokensTAGSSmMinWidthConfig.Not the same as the already-filed issues
prefix + hash. That fix is cosmetic by its own commit message ("the emitted@unboxedtype body is unchanged"). The giant enumerated body and the CSS-keyword constructor leakage into the collision namespace both remain. This issue is about eliminating them at the source, not shortening their names.stringwhen a DeepPartial wrapper deepens the graph (blend 0.0.38-beta.1: +310 record→string regressions, source unchanged) #205 (open): record token fields →stringviaMAX_DEPTH+healGhostRecordsrejection. Same upstream trigger (DeepPartial<ComponentTokenType>), but a structural-record path. This issue is the csstype-value-union path: fields that stay typed but expand every CSS keyword instead of beingstring.TS input → current output → expected output
TypeScript (via
DeepPartial<ComponentTokenType>):Current ReScript output (beta.1):
Expected (what
isCssTypealready produces for a directly-referenced csstype value):Suspected root cause
isCssType(extract.mjs:1092-1099) recognises csstype only by thedeclaration's source-file path (
/csstype/):When the value is reached through the homomorphic mapped type
DeepPartial<ComponentTokenType>, the checker hands back a synthesized /apparent union of string-literal + globals types whose
aliasSymbol/declaration provenance no longer points at the
csstypepackage file — soisCssTypereturnsfalse, the csstype→stringshortcut is skipped, and theunion falls through to full member enumeration (→ #200's name bloat, cosmetically
capped by #201, plus the constructor leakage this issue is about).
Directly-referenced csstype values (not wrapped) still collapse to
stringcorrectly — which is why beta.0 had 0 of these and beta.1 has 872.
Fix direction
Make csstype detection structural, not purely path-based, so it survives
mapped-type wrapping — e.g. recognise a union that is dominated by the csstype
Globalsset (-moz-initial | inherit | initial | revert | revert-layer | unset)and/or the CSS named-color vocabulary, optionally with a
(string & {})open arm,and map it to
string. Alternatively, unwrapDeepPartial<>/ homomorphicmapped types back to the source property type before classifying, so the original
aliasSymbol(and its csstype declaration file) is still visible toisCssType.Collapsing at the source removes the 872 giant bodies entirely (not just their
names), stops the CSS-keyword constructor leakage into
ContextSharedTypes, andshould also shrink the type graph enough to relieve part of #205.
Repro
blend
0.0.38-beta.1is already pinned in the benchmark, so this reproducesin-repo. First observed in the downstream regen
blend-rescript#147, which
was generated against the last published bindgen (
1.4.0-beta.1, pre-#201).