@@ -22,6 +22,7 @@ import type { Writable } from './types'
2222import { DefaultMap } from './utils/default-map'
2323import { dimensions } from './utils/dimensions'
2424import { isPositiveInteger , isValidSpacingMultiplier } from './utils/infer-data-type'
25+ import './utils/map-get-or-insert'
2526import { replaceObject } from './utils/replace-object'
2627import { segment } from './utils/segment'
2728import { toKeyPath } from './utils/to-key-path'
@@ -93,14 +94,8 @@ interface DesignSystem extends BaseDesignSystem {
9394 [ CONVERTER_KEY ] : ( input : string , options ?: Convert ) => [ string , CandidateModifier | null ]
9495 [ SPACING_KEY ] : DefaultMap < string , number | null > | null
9596 [ UTILITY_SIGNATURE_KEY ] : DefaultMap < SignatureOptions , DefaultMap < string , string | Symbol > >
96- [ STATIC_UTILITIES_KEY ] : DefaultMap <
97- SignatureOptions ,
98- DefaultMap < string , DefaultMap < string , Set < string > > >
99- >
100- [ UTILITY_PROPERTIES_KEY ] : DefaultMap <
101- SignatureOptions ,
102- DefaultMap < string , DefaultMap < string , Set < string > > >
103- >
97+ [ STATIC_UTILITIES_KEY ] : Map < SignatureOptions , Map < string , Map < string , Set < string > > > >
98+ [ UTILITY_PROPERTIES_KEY ] : Map < SignatureOptions , Map < string , Map < string , Set < string > > > >
10499 [ PRE_COMPUTED_UTILITIES_KEY ] : DefaultMap < SignatureOptions , DefaultMap < string , string [ ] > >
105100 [ VARIANT_SIGNATURE_KEY ] : DefaultMap < string , string | Symbol >
106101 [ PRE_COMPUTED_VARIANTS_KEY ] : DefaultMap < string , string [ ] >
@@ -122,7 +117,7 @@ export function prepareDesignSystemStorage(
122117 designSystem . storage [ SPACING_KEY ] ??= createSpacingCache ( designSystem , options )
123118 designSystem . storage [ UTILITY_SIGNATURE_KEY ] ??= createUtilitySignatureCache ( designSystem )
124119 designSystem . storage [ STATIC_UTILITIES_KEY ] ??= createStaticUtilitiesCache ( )
125- designSystem . storage [ UTILITY_PROPERTIES_KEY ] ??= createUtilityPropertiesCache ( designSystem )
120+ designSystem . storage [ UTILITY_PROPERTIES_KEY ] ??= createUtilityPropertiesCache ( )
126121 designSystem . storage [ PRE_COMPUTED_UTILITIES_KEY ] ??= createPreComputedUtilitiesCache ( designSystem )
127122 designSystem . storage [ VARIANT_SIGNATURE_KEY ] ??= createVariantSignatureCache ( designSystem )
128123 designSystem . storage [ PRE_COMPUTED_VARIANTS_KEY ] ??= createPreComputedVariantsCache ( designSystem )
@@ -246,28 +241,26 @@ function collapseCandidates(options: InternalCanonicalizeOptions, candidates: st
246241
247242 function collapseGroup ( candidates : string [ ] ) {
248243 let signatureOptions = options . signatureOptions
249- let computeUtilitiesPropertiesLookup =
250- designSystem . storage [ UTILITY_PROPERTIES_KEY ] . get ( signatureOptions )
251- let staticUtilities = designSystem . storage [ STATIC_UTILITIES_KEY ] . get ( signatureOptions )
244+ let staticUtilities = getStaticUtilitiesLookup ( designSystem , signatureOptions )
252245
253246 // For each candidate, compute the used properties and values. E.g.: `mt-1` → `margin-top` → `0.25rem`
254247 //
255248 // NOTE: Currently assuming we are dealing with static utilities only. This
256249 // will change the moment we have `@utility` for most built-ins.
257250 let candidatePropertiesValues = candidates . map ( ( candidate ) =>
258- computeUtilitiesPropertiesLookup . get ( candidate ) ,
251+ getUtilityPropertiesLookup ( designSystem , signatureOptions , candidate ) ,
259252 )
260253
261254 // Hard-coded optimization: if any candidate sets `line-height` and another
262255 // candidate sets `font-size`, we pre-compute the `text-*` utilities with
263256 // this line-height to try and collapse to those combined values.
264- if ( candidatePropertiesValues . some ( ( x ) => x . has ( 'line-height' ) ) ) {
257+ if ( candidatePropertiesValues . some ( ( x ) => ( x . get ( 'line-height' ) ?. size ?? 0 ) > 0 ) ) {
265258 let fontSizeNames = designSystem . theme . keysInNamespaces ( [ '--text' ] )
266259 if ( fontSizeNames . length > 0 ) {
267260 let interestingLineHeights = new Set < string | number > ( )
268261 let seenLineHeights = new Set < string > ( )
269262 for ( let pairs of candidatePropertiesValues ) {
270- for ( let lineHeight of pairs . get ( 'line-height' ) ) {
263+ for ( let lineHeight of pairs . get ( 'line-height' ) ?? [ ] ) {
271264 if ( seenLineHeights . has ( lineHeight ) ) continue
272265 seenLineHeights . add ( lineHeight )
273266
@@ -277,13 +270,21 @@ function collapseCandidates(options: InternalCanonicalizeOptions, candidates: st
277270 interestingLineHeights . add ( bareValue )
278271
279272 for ( let name of fontSizeNames ) {
280- computeUtilitiesPropertiesLookup . get ( `text-${ name } /${ bareValue } ` )
273+ getUtilityPropertiesLookup (
274+ designSystem ,
275+ signatureOptions ,
276+ `text-${ name } /${ bareValue } ` ,
277+ )
281278 }
282279 } else {
283280 interestingLineHeights . add ( lineHeight )
284281
285282 for ( let name of fontSizeNames ) {
286- computeUtilitiesPropertiesLookup . get ( `text-${ name } /[${ lineHeight } ]` )
283+ getUtilityPropertiesLookup (
284+ designSystem ,
285+ signatureOptions ,
286+ `text-${ name } /[${ lineHeight } ]` ,
287+ )
287288 }
288289 }
289290 }
@@ -292,15 +293,23 @@ function collapseCandidates(options: InternalCanonicalizeOptions, candidates: st
292293
293294 let seenFontSizes = new Set < string > ( )
294295 for ( let pairs of candidatePropertiesValues ) {
295- for ( let fontSize of pairs . get ( 'font-size' ) ) {
296+ for ( let fontSize of pairs . get ( 'font-size' ) || [ ] ) {
296297 if ( seenFontSizes . has ( fontSize ) ) continue
297298 seenFontSizes . add ( fontSize )
298299
299300 for ( let lineHeight of interestingLineHeights ) {
300301 if ( isValidSpacingMultiplier ( lineHeight ) ) {
301- computeUtilitiesPropertiesLookup . get ( `text-[${ fontSize } ]/${ lineHeight } ` )
302+ getUtilityPropertiesLookup (
303+ designSystem ,
304+ signatureOptions ,
305+ `text-[${ fontSize } ]/${ lineHeight } ` ,
306+ )
302307 } else {
303- computeUtilitiesPropertiesLookup . get ( `text-[${ fontSize } ]/[${ lineHeight } ]` )
308+ getUtilityPropertiesLookup (
309+ designSystem ,
310+ signatureOptions ,
311+ `text-[${ fontSize } ]/[${ lineHeight } ]` ,
312+ )
304313 }
305314 }
306315 }
@@ -317,7 +326,12 @@ function collapseCandidates(options: InternalCanonicalizeOptions, candidates: st
317326 let result : Set < string > | null = null
318327 for ( let property of propertyValues . keys ( ) ) {
319328 let otherUtilities = new Set < string > ( )
320- for ( let group of staticUtilities . get ( property ) . values ( ) ) {
329+ let groupsByValue = staticUtilities . get ( property )
330+ if ( ! groupsByValue ) {
331+ return new Set < string > ( )
332+ }
333+
334+ for ( let group of groupsByValue . values ( ) ) {
321335 for ( let candidate of group ) {
322336 otherUtilities . add ( candidate )
323337 }
@@ -2278,49 +2292,85 @@ function resolveVariablesInValue(value: string, designSystem: DesignSystem): str
22782292// Index all static utilities by property and value
22792293const STATIC_UTILITIES_KEY = Symbol ( )
22802294function createStaticUtilitiesCache ( ) : DesignSystem [ 'storage' ] [ typeof STATIC_UTILITIES_KEY ] {
2281- return new DefaultMap ( ( _optiones : SignatureOptions ) => {
2282- return new DefaultMap ( ( _property : string ) => {
2283- return new DefaultMap ( ( _value : string ) => {
2284- return new Set < string > ( )
2285- } )
2286- } )
2287- } )
2295+ return new Map ( )
22882296}
22892297
22902298const UTILITY_PROPERTIES_KEY = Symbol ( )
2291- function createUtilityPropertiesCache (
2299+ function createUtilityPropertiesCache ( ) : DesignSystem [ 'storage' ] [ typeof UTILITY_PROPERTIES_KEY ] {
2300+ return new Map ( )
2301+ }
2302+
2303+ function getStaticUtilitiesLookup (
22922304 designSystem : DesignSystem ,
2293- ) : DesignSystem [ 'storage' ] [ typeof UTILITY_PROPERTIES_KEY ] {
2294- return new DefaultMap ( ( options : SignatureOptions ) => {
2295- return new DefaultMap ( ( className ) => {
2296- let localPropertyValueLookup = new DefaultMap ( ( _property ) => new Set < string > ( ) )
2305+ options : SignatureOptions ,
2306+ ) : Map < string , Map < string , Set < string > > > {
2307+ let lookup = designSystem . storage [ STATIC_UTILITIES_KEY ] . get ( options )
2308+ if ( lookup ) return lookup
2309+
2310+ return designSystem . storage [ STATIC_UTILITIES_KEY ] . getOrInsert ( options , new Map ( ) )
2311+ }
2312+
2313+ function getUtilityPropertiesCache (
2314+ designSystem : DesignSystem ,
2315+ options : SignatureOptions ,
2316+ ) : Map < string , Map < string , Set < string > > > {
2317+ let cache = designSystem . storage [ UTILITY_PROPERTIES_KEY ] . get ( options )
2318+ if ( cache ) return cache
2319+
2320+ return designSystem . storage [ UTILITY_PROPERTIES_KEY ] . getOrInsert ( options , new Map ( ) )
2321+ }
2322+
2323+ function getUtilityPropertiesLookup (
2324+ designSystem : DesignSystem ,
2325+ options : SignatureOptions ,
2326+ className : string ,
2327+ ) : Map < string , Set < string > > {
2328+ let utilityPropertiesCache = getUtilityPropertiesCache ( designSystem , options )
2329+ let localPropertyValueLookup = utilityPropertiesCache . get ( className )
2330+ if ( localPropertyValueLookup ) return localPropertyValueLookup
2331+
2332+ localPropertyValueLookup = new Map < string , Set < string > > ( )
2333+ utilityPropertiesCache . set ( className , localPropertyValueLookup )
2334+
2335+ let resolvedClassName = className
2336+ if ( designSystem . theme . prefix && ! resolvedClassName . startsWith ( designSystem . theme . prefix ) ) {
2337+ resolvedClassName = `${ designSystem . theme . prefix } :${ resolvedClassName } `
2338+ }
2339+
2340+ let parsed = designSystem . parseCandidate ( resolvedClassName )
2341+ if ( parsed . length === 0 ) return localPropertyValueLookup
22972342
2298- if ( designSystem . theme . prefix && ! className . startsWith ( designSystem . theme . prefix ) ) {
2299- className = `${ designSystem . theme . prefix } :${ className } `
2343+ let staticUtilities = getStaticUtilitiesLookup ( designSystem , options )
2344+
2345+ walk (
2346+ canonicalizeAst (
2347+ designSystem ,
2348+ designSystem . compileAstNodes ( parsed [ 0 ] ) . map ( ( x ) => cloneAstNode ( x . node ) ) ,
2349+ options ,
2350+ ) ,
2351+ ( node ) => {
2352+ if ( node . kind !== 'declaration' ) return
2353+
2354+ let values = localPropertyValueLookup . get ( node . property )
2355+ if ( ! values ) {
2356+ values = localPropertyValueLookup . getOrInsert ( node . property , new Set < string > ( ) )
23002357 }
2301- let parsed = designSystem . parseCandidate ( className )
2302- if ( parsed . length === 0 ) return localPropertyValueLookup
2303-
2304- walk (
2305- canonicalizeAst (
2306- designSystem ,
2307- designSystem . compileAstNodes ( parsed [ 0 ] ) . map ( ( x ) => cloneAstNode ( x . node ) ) ,
2308- options ,
2309- ) ,
2310- ( node ) => {
2311- if ( node . kind === 'declaration' ) {
2312- localPropertyValueLookup . get ( node . property ) . add ( node . value ! )
2313- designSystem . storage [ STATIC_UTILITIES_KEY ] . get ( options )
2314- . get ( node . property )
2315- . get ( node . value ! )
2316- . add ( className )
2317- }
2318- } ,
2319- )
2358+ values . add ( node . value ! )
23202359
2321- return localPropertyValueLookup
2322- } )
2323- } )
2360+ let utilitiesByValue = staticUtilities . get ( node . property )
2361+ if ( ! utilitiesByValue ) {
2362+ utilitiesByValue = staticUtilities . getOrInsert ( node . property , new Map ( ) )
2363+ }
2364+
2365+ let utilities = utilitiesByValue . get ( node . value ! )
2366+ if ( ! utilities ) {
2367+ utilities = utilitiesByValue . getOrInsert ( node . value ! , new Set < string > ( ) )
2368+ }
2369+ utilities . add ( resolvedClassName )
2370+ } ,
2371+ )
2372+
2373+ return localPropertyValueLookup
23242374}
23252375
23262376// For all static utilities in the system, compute a lookup table that maps the
@@ -2356,7 +2406,7 @@ function createPreComputedUtilitiesCache(
23562406 }
23572407
23582408 lookup . get ( signature ) . push ( className )
2359- designSystem . storage [ UTILITY_PROPERTIES_KEY ] . get ( options ) . get ( className )
2409+ getUtilityPropertiesLookup ( designSystem , options , className )
23602410
23612411 for ( let modifier of meta . modifiers ) {
23622412 // Modifiers representing numbers can be computed and don't need to be
@@ -2370,7 +2420,7 @@ function createPreComputedUtilitiesCache(
23702420 let signature = signatures . get ( classNameWithModifier )
23712421 if ( typeof signature !== 'string' ) continue
23722422 lookup . get ( signature ) . push ( classNameWithModifier )
2373- designSystem . storage [ UTILITY_PROPERTIES_KEY ] . get ( options ) . get ( classNameWithModifier )
2423+ getUtilityPropertiesLookup ( designSystem , options , classNameWithModifier )
23742424 }
23752425 }
23762426
0 commit comments