rnwind 0.0.5 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/core/parser/declaration.cjs +5 -0
- package/lib/cjs/core/parser/declaration.cjs.map +1 -1
- package/lib/cjs/core/parser/tokens.cjs +15 -0
- package/lib/cjs/core/parser/tokens.cjs.map +1 -1
- package/lib/cjs/core/parser/tokens.d.ts +11 -0
- package/lib/cjs/runtime/resolve.cjs +58 -6
- package/lib/cjs/runtime/resolve.cjs.map +1 -1
- package/lib/cjs/runtime/resolve.d.ts +5 -0
- package/lib/esm/core/parser/declaration.mjs +6 -1
- package/lib/esm/core/parser/declaration.mjs.map +1 -1
- package/lib/esm/core/parser/tokens.d.ts +11 -0
- package/lib/esm/core/parser/tokens.mjs +15 -1
- package/lib/esm/core/parser/tokens.mjs.map +1 -1
- package/lib/esm/runtime/resolve.d.ts +5 -0
- package/lib/esm/runtime/resolve.mjs +58 -6
- package/lib/esm/runtime/resolve.mjs.map +1 -1
- package/package.json +1 -1
- package/src/core/parser/declaration.ts +6 -1
- package/src/core/parser/tokens.ts +15 -0
- package/src/runtime/resolve.ts +63 -6
|
@@ -435,6 +435,21 @@ function unquoteCssString(text: string): string {
|
|
|
435
435
|
return inner
|
|
436
436
|
}
|
|
437
437
|
|
|
438
|
+
/**
|
|
439
|
+
* Coerce a CSS `font-family` value into the SINGLE typeface name RN wants.
|
|
440
|
+
* CSS font-family is a fallback LIST (`"Montserrat", sans-serif`), but RN's
|
|
441
|
+
* `fontFamily` takes one family — so take the first entry and strip its
|
|
442
|
+
* quotes. This is what lets the standard Tailwind convention
|
|
443
|
+
* (`--font-display: "Name", sans-serif`) work out of the box: `font-display`
|
|
444
|
+
* resolves to `{ fontFamily: 'Name' }`, not the raw quoted list.
|
|
445
|
+
* @param value Resolved `font-family` value (possibly a quoted list).
|
|
446
|
+
* @returns Bare first-family name.
|
|
447
|
+
*/
|
|
448
|
+
export function coerceFontFamily(value: string): string {
|
|
449
|
+
const first = value.split(',')[0]?.trim() ?? value
|
|
450
|
+
return unquoteCssString(first)
|
|
451
|
+
}
|
|
452
|
+
|
|
438
453
|
/**
|
|
439
454
|
* Substitute every `var(--name [, fallback])` reference in `text` with
|
|
440
455
|
* the value from `table` (or the fallback clause when the name misses).
|
package/src/runtime/resolve.ts
CHANGED
|
@@ -43,6 +43,33 @@ const resolvedCache = new Map<string, ResolvedCss>()
|
|
|
43
43
|
/** Version the cache was last valid for (`getStyleVersion()` + {@link registryVersion}). */
|
|
44
44
|
let cachedFor = -1
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Hard ceiling on the resolved cache. The cache is pure memoisation, so
|
|
48
|
+
* eviction only costs a re-resolve (sub-µs) — never correctness. Build
|
|
49
|
+
* molecules are NOT in here; they live permanently in `molecules`.
|
|
50
|
+
*/
|
|
51
|
+
const MAX_RESOLVED_CACHE = 2048
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Store a resolved result, bulk-evicting the OLDEST half when the cache
|
|
55
|
+
* hits {@link MAX_RESOLVED_CACHE}. `Map` preserves insertion order, so the
|
|
56
|
+
* first keys are the oldest. Bulk eviction keeps the hot (cache-hit) path
|
|
57
|
+
* free of per-access LRU bookkeeping at the cost of an occasional small
|
|
58
|
+
* recompute burst under sustained pressure (web / long sessions).
|
|
59
|
+
* @param key Cache key.
|
|
60
|
+
* @param value Resolved result to store.
|
|
61
|
+
*/
|
|
62
|
+
function cacheResolved(key: string, value: ResolvedCss): void {
|
|
63
|
+
if (resolvedCache.size >= MAX_RESOLVED_CACHE) {
|
|
64
|
+
let drop = resolvedCache.size >> 1
|
|
65
|
+
for (const oldKey of resolvedCache.keys()) {
|
|
66
|
+
resolvedCache.delete(oldKey)
|
|
67
|
+
if (--drop <= 0) break
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
resolvedCache.set(key, value)
|
|
71
|
+
}
|
|
72
|
+
|
|
46
73
|
/** A unit-square gradient endpoint. */
|
|
47
74
|
interface GradientPoint {
|
|
48
75
|
readonly x: number
|
|
@@ -121,13 +148,17 @@ const stateSignatureCache = new WeakMap<RnwindState, string>()
|
|
|
121
148
|
|
|
122
149
|
/**
|
|
123
150
|
* Cache key dimension for the reactive context — everything that can
|
|
124
|
-
* change a resolved style.
|
|
151
|
+
* change a resolved style. Uses the breakpoint TIER (`activeBreakpoint`),
|
|
152
|
+
* NOT the raw `windowWidth`: two widths in the same tier gate `md:*` atoms
|
|
153
|
+
* identically, so they resolve the same. This collapses the window axis
|
|
154
|
+
* from "every pixel" to ~6 values, bounding the cache on resizable
|
|
155
|
+
* surfaces (web / desktop) without changing any result.
|
|
125
156
|
* @param state Rnwind context.
|
|
126
157
|
* @returns Compact signature string.
|
|
127
158
|
*/
|
|
128
159
|
function stateSignature(state: RnwindState): string {
|
|
129
160
|
const { insets } = state
|
|
130
|
-
return `${state.scheme}|${insets.top},${insets.right},${insets.bottom},${insets.left}|${state.fontScale}|${state.
|
|
161
|
+
return `${state.scheme}|${insets.top},${insets.right},${insets.bottom},${insets.left}|${state.fontScale}|${state.activeBreakpoint}`
|
|
131
162
|
}
|
|
132
163
|
|
|
133
164
|
/**
|
|
@@ -303,6 +334,22 @@ function attachFeatures(base: ResolvedCss, tokens: readonly string[]): ResolvedC
|
|
|
303
334
|
return result
|
|
304
335
|
}
|
|
305
336
|
|
|
337
|
+
/**
|
|
338
|
+
* Flatten the per-atom style array into ONE object — a *runtime molecule*.
|
|
339
|
+
* RN flattens a style array left-to-right (later wins), which is exactly
|
|
340
|
+
* `Object.assign` semantics, so the merged object renders identically
|
|
341
|
+
* while giving dynamic (cva / clsx) classNames the same single-object
|
|
342
|
+
* shape a build-time molecule has. The caller caches the result per
|
|
343
|
+
* `(className · state)`, so the merge runs once per unique context.
|
|
344
|
+
* @param array Per-atom style array from `lookupCss`.
|
|
345
|
+
* @returns Single merged style object.
|
|
346
|
+
*/
|
|
347
|
+
function mergeStyleArray(array: readonly unknown[]): Record<string, unknown> {
|
|
348
|
+
const out: Record<string, unknown> = {}
|
|
349
|
+
for (const entry of array) if (entry && typeof entry === 'object') Object.assign(out, entry)
|
|
350
|
+
return out
|
|
351
|
+
}
|
|
352
|
+
|
|
306
353
|
/**
|
|
307
354
|
* Compose a resolved style with a caller-supplied inline style (user wins).
|
|
308
355
|
* @param style
|
|
@@ -349,7 +396,7 @@ export function resolve(
|
|
|
349
396
|
const normalized = normalizeClassName(className)
|
|
350
397
|
if (normalized.length === 0) {
|
|
351
398
|
const empty: ResolvedCss = { style: EMPTY }
|
|
352
|
-
|
|
399
|
+
cacheResolved(key, empty)
|
|
353
400
|
return userStyle === undefined || userStyle === null ? empty : { style: [userStyle] }
|
|
354
401
|
}
|
|
355
402
|
// Molecules are static pre-merges; anything carrying `active:`/`focus:`
|
|
@@ -357,11 +404,16 @@ export function resolve(
|
|
|
357
404
|
const tokens = normalized.split(' ')
|
|
358
405
|
const molecule = interactState ? undefined : molecules[state.scheme]?.[normalized] ?? molecules[COMMON_SCHEME]?.[normalized]
|
|
359
406
|
// Feature-only tokens (gradient / haptic / truncate) carry no style — keep
|
|
360
|
-
// them out of the atom lookup so they don't warn as "unknown class".
|
|
407
|
+
// them out of the atom lookup so they don't warn as "unknown class". The
|
|
408
|
+
// atom array is merged into ONE object (a runtime molecule) so dynamic
|
|
409
|
+
// (cva / clsx) classNames get the same single-object shape as a build
|
|
410
|
+
// molecule; the cache below pins the context, so the merge is correct.
|
|
361
411
|
const style =
|
|
362
|
-
molecule === undefined
|
|
412
|
+
molecule === undefined
|
|
413
|
+
? mergeStyleArray(lookupCss(tokens.filter((token) => !isFeatureOnlyToken(token)).join(' '), state, undefined, interactState))
|
|
414
|
+
: molecule
|
|
363
415
|
const base = attachFeatures({ style }, tokens)
|
|
364
|
-
|
|
416
|
+
cacheResolved(key, base)
|
|
365
417
|
return userStyle === undefined || userStyle === null ? base : { ...base, style: withUserStyle(base.style, userStyle) }
|
|
366
418
|
}
|
|
367
419
|
|
|
@@ -378,4 +430,9 @@ export function __resetResolveState(): void {
|
|
|
378
430
|
cachedFor = -1
|
|
379
431
|
}
|
|
380
432
|
|
|
433
|
+
/** Test-only — current resolved-cache entry count + its hard ceiling. */
|
|
434
|
+
export function __resolveCacheStats(): { size: number; max: number } {
|
|
435
|
+
return { size: resolvedCache.size, max: MAX_RESOLVED_CACHE }
|
|
436
|
+
}
|
|
437
|
+
|
|
381
438
|
export {normalizeClassName} from '../core/normalize-classname'
|