rnwind 0.0.4 → 0.0.6

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.
Files changed (127) hide show
  1. package/lib/cjs/core/normalize-classname.cjs +25 -0
  2. package/lib/cjs/core/normalize-classname.cjs.map +1 -0
  3. package/lib/cjs/core/normalize-classname.d.ts +10 -0
  4. package/lib/cjs/core/style-builder/build-style.cjs +258 -58
  5. package/lib/cjs/core/style-builder/build-style.cjs.map +1 -1
  6. package/lib/cjs/core/style-builder/build-style.d.ts +6 -1
  7. package/lib/cjs/core/style-builder/union-builder.cjs +37 -3
  8. package/lib/cjs/core/style-builder/union-builder.cjs.map +1 -1
  9. package/lib/cjs/core/style-builder/union-builder.d.ts +21 -1
  10. package/lib/cjs/metro/dts.cjs +7 -16
  11. package/lib/cjs/metro/dts.cjs.map +1 -1
  12. package/lib/cjs/metro/dts.d.ts +2 -4
  13. package/lib/cjs/metro/state.cjs +30 -78
  14. package/lib/cjs/metro/state.cjs.map +1 -1
  15. package/lib/cjs/metro/state.d.ts +8 -25
  16. package/lib/cjs/metro/transformer.cjs +193 -34
  17. package/lib/cjs/metro/transformer.cjs.map +1 -1
  18. package/lib/cjs/metro/with-config.cjs +2 -2
  19. package/lib/cjs/metro/with-config.cjs.map +1 -1
  20. package/lib/cjs/metro/with-config.d.ts +11 -26
  21. package/lib/cjs/metro/wrap-imports.cjs +273 -0
  22. package/lib/cjs/metro/wrap-imports.cjs.map +1 -0
  23. package/lib/cjs/metro/wrap-imports.d.ts +26 -0
  24. package/lib/cjs/runtime/components/rnwind-provider.cjs +0 -17
  25. package/lib/cjs/runtime/components/rnwind-provider.cjs.map +1 -1
  26. package/lib/cjs/runtime/components/rnwind-provider.d.ts +0 -14
  27. package/lib/cjs/runtime/hooks/use-css.cjs +16 -10
  28. package/lib/cjs/runtime/hooks/use-css.cjs.map +1 -1
  29. package/lib/cjs/runtime/hooks/use-css.d.ts +15 -9
  30. package/lib/cjs/runtime/index.cjs +11 -13
  31. package/lib/cjs/runtime/index.cjs.map +1 -1
  32. package/lib/cjs/runtime/index.d.ts +4 -9
  33. package/lib/cjs/runtime/lookup-css.cjs +10 -0
  34. package/lib/cjs/runtime/lookup-css.cjs.map +1 -1
  35. package/lib/cjs/runtime/lookup-css.d.ts +7 -0
  36. package/lib/cjs/runtime/resolve.cjs +400 -0
  37. package/lib/cjs/runtime/resolve.cjs.map +1 -0
  38. package/lib/cjs/runtime/resolve.d.ts +66 -0
  39. package/lib/cjs/runtime/wrap.cjs +254 -0
  40. package/lib/cjs/runtime/wrap.cjs.map +1 -0
  41. package/lib/cjs/runtime/wrap.d.ts +37 -0
  42. package/lib/cjs/testing/index.cjs +81 -50
  43. package/lib/cjs/testing/index.cjs.map +1 -1
  44. package/lib/esm/core/normalize-classname.d.ts +10 -0
  45. package/lib/esm/core/normalize-classname.mjs +23 -0
  46. package/lib/esm/core/normalize-classname.mjs.map +1 -0
  47. package/lib/esm/core/style-builder/build-style.d.ts +6 -1
  48. package/lib/esm/core/style-builder/build-style.mjs +258 -58
  49. package/lib/esm/core/style-builder/build-style.mjs.map +1 -1
  50. package/lib/esm/core/style-builder/union-builder.d.ts +21 -1
  51. package/lib/esm/core/style-builder/union-builder.mjs +37 -3
  52. package/lib/esm/core/style-builder/union-builder.mjs.map +1 -1
  53. package/lib/esm/metro/dts.d.ts +2 -4
  54. package/lib/esm/metro/dts.mjs +7 -16
  55. package/lib/esm/metro/dts.mjs.map +1 -1
  56. package/lib/esm/metro/state.d.ts +8 -25
  57. package/lib/esm/metro/state.mjs +30 -76
  58. package/lib/esm/metro/state.mjs.map +1 -1
  59. package/lib/esm/metro/transformer.mjs +194 -35
  60. package/lib/esm/metro/transformer.mjs.map +1 -1
  61. package/lib/esm/metro/with-config.d.ts +11 -26
  62. package/lib/esm/metro/with-config.mjs +2 -2
  63. package/lib/esm/metro/with-config.mjs.map +1 -1
  64. package/lib/esm/metro/wrap-imports.d.ts +26 -0
  65. package/lib/esm/metro/wrap-imports.mjs +250 -0
  66. package/lib/esm/metro/wrap-imports.mjs.map +1 -0
  67. package/lib/esm/runtime/components/rnwind-provider.d.ts +0 -14
  68. package/lib/esm/runtime/components/rnwind-provider.mjs +1 -17
  69. package/lib/esm/runtime/components/rnwind-provider.mjs.map +1 -1
  70. package/lib/esm/runtime/hooks/use-css.d.ts +15 -9
  71. package/lib/esm/runtime/hooks/use-css.mjs +16 -10
  72. package/lib/esm/runtime/hooks/use-css.mjs.map +1 -1
  73. package/lib/esm/runtime/index.d.ts +4 -9
  74. package/lib/esm/runtime/index.mjs +4 -4
  75. package/lib/esm/runtime/index.mjs.map +1 -1
  76. package/lib/esm/runtime/lookup-css.d.ts +7 -0
  77. package/lib/esm/runtime/lookup-css.mjs +10 -1
  78. package/lib/esm/runtime/lookup-css.mjs.map +1 -1
  79. package/lib/esm/runtime/resolve.d.ts +66 -0
  80. package/lib/esm/runtime/resolve.mjs +393 -0
  81. package/lib/esm/runtime/resolve.mjs.map +1 -0
  82. package/lib/esm/runtime/wrap.d.ts +37 -0
  83. package/lib/esm/runtime/wrap.mjs +251 -0
  84. package/lib/esm/runtime/wrap.mjs.map +1 -0
  85. package/lib/esm/testing/index.mjs +84 -53
  86. package/lib/esm/testing/index.mjs.map +1 -1
  87. package/package.json +2 -1
  88. package/src/core/normalize-classname.ts +19 -0
  89. package/src/core/style-builder/build-style.ts +286 -55
  90. package/src/core/style-builder/union-builder.ts +36 -3
  91. package/src/metro/dts.ts +7 -19
  92. package/src/metro/state.ts +29 -74
  93. package/src/metro/transformer.ts +190 -34
  94. package/src/metro/with-config.ts +13 -28
  95. package/src/metro/wrap-imports.ts +260 -0
  96. package/src/runtime/components/rnwind-provider.tsx +0 -17
  97. package/src/runtime/hooks/use-css.ts +17 -11
  98. package/src/runtime/index.ts +3 -26
  99. package/src/runtime/lookup-css.ts +10 -0
  100. package/src/runtime/resolve.ts +438 -0
  101. package/src/runtime/wrap.tsx +267 -0
  102. package/src/testing/index.ts +106 -56
  103. package/lib/cjs/core/parser/text-truncate.cjs +0 -78
  104. package/lib/cjs/core/parser/text-truncate.cjs.map +0 -1
  105. package/lib/cjs/metro/transform-ast.cjs +0 -1472
  106. package/lib/cjs/metro/transform-ast.cjs.map +0 -1
  107. package/lib/cjs/metro/transform-ast.d.ts +0 -88
  108. package/lib/cjs/runtime/haptics.cjs +0 -113
  109. package/lib/cjs/runtime/haptics.cjs.map +0 -1
  110. package/lib/cjs/runtime/haptics.d.ts +0 -48
  111. package/lib/cjs/runtime/interactive-box.cjs +0 -35
  112. package/lib/cjs/runtime/interactive-box.cjs.map +0 -1
  113. package/lib/cjs/runtime/interactive-box.d.ts +0 -40
  114. package/lib/esm/core/parser/text-truncate.mjs +0 -75
  115. package/lib/esm/core/parser/text-truncate.mjs.map +0 -1
  116. package/lib/esm/metro/transform-ast.d.ts +0 -88
  117. package/lib/esm/metro/transform-ast.mjs +0 -1451
  118. package/lib/esm/metro/transform-ast.mjs.map +0 -1
  119. package/lib/esm/runtime/haptics.d.ts +0 -48
  120. package/lib/esm/runtime/haptics.mjs +0 -110
  121. package/lib/esm/runtime/haptics.mjs.map +0 -1
  122. package/lib/esm/runtime/interactive-box.d.ts +0 -40
  123. package/lib/esm/runtime/interactive-box.mjs +0 -33
  124. package/lib/esm/runtime/interactive-box.mjs.map +0 -1
  125. package/src/metro/transform-ast.ts +0 -1729
  126. package/src/runtime/haptics.ts +0 -120
  127. package/src/runtime/interactive-box.tsx +0 -57
@@ -0,0 +1,400 @@
1
+ 'use strict';
2
+
3
+ var lookupCss = require('./lookup-css.cjs');
4
+ var normalizeClassname = require('../core/normalize-classname.cjs');
5
+
6
+ /**
7
+ * Rich className resolver — the runtime heart of the wrap / `useCss`.
8
+ *
9
+ * Resolution order, per className string:
10
+ * 1. **Molecule** — a build-time PRE-MERGED single style object for the
11
+ * whole literal className (per scheme). One map lookup returns it by
12
+ * reference: no array, no merge, no per-atom loop. The common case.
13
+ * 2. **Atom fallback** — for a className the scanner never saw (a
14
+ * runtime-built string like `` `${className} px-2` ``) OR one that
15
+ * carries context-dependent atoms (`pt-safe`, `text-base`, `md:*`),
16
+ * fall back to per-atom resolution via `lookupCss`, which folds in
17
+ * insets / fontScale / breakpoint / scheme.
18
+ *
19
+ * Results are cached by `(normalized className, scheme, insets, fontScale,
20
+ * breakpoint)` so repeated renders return the SAME reference until the
21
+ * reactive context changes. Atoms / molecules / features all live in
22
+ * build-time registries the generated `.rnwind/*.js` modules populate.
23
+ */
24
+ /** Always-loaded fallback scheme key. */
25
+ const COMMON_SCHEME = 'common';
26
+ /** Empty style sentinel. */
27
+ const EMPTY = [];
28
+ /** scheme → normalized className → pre-merged style object. */
29
+ let molecules = Object.create(null);
30
+ /** atom name → gradient role + resolved colour. */
31
+ let gradients = Object.create(null);
32
+ /** atom name (incl. `active:`/`focus:` prefix) → haptic request. */
33
+ let haptics = Object.create(null);
34
+ /** Bumps on any molecule/gradient/haptic registration. */
35
+ let registryVersion = 0;
36
+ /** Per-(className·state) resolved cache — strong references between context changes. */
37
+ const resolvedCache = new Map();
38
+ /** Version the cache was last valid for (`getStyleVersion()` + {@link registryVersion}). */
39
+ let cachedFor = -1;
40
+ /**
41
+ * Hard ceiling on the resolved cache. The cache is pure memoisation, so
42
+ * eviction only costs a re-resolve (sub-µs) — never correctness. Build
43
+ * molecules are NOT in here; they live permanently in `molecules`.
44
+ */
45
+ const MAX_RESOLVED_CACHE = 2048;
46
+ /**
47
+ * Store a resolved result, bulk-evicting the OLDEST half when the cache
48
+ * hits {@link MAX_RESOLVED_CACHE}. `Map` preserves insertion order, so the
49
+ * first keys are the oldest. Bulk eviction keeps the hot (cache-hit) path
50
+ * free of per-access LRU bookkeeping at the cost of an occasional small
51
+ * recompute burst under sustained pressure (web / long sessions).
52
+ * @param key Cache key.
53
+ * @param value Resolved result to store.
54
+ */
55
+ function cacheResolved(key, value) {
56
+ if (resolvedCache.size >= MAX_RESOLVED_CACHE) {
57
+ let drop = resolvedCache.size >> 1;
58
+ for (const oldKey of resolvedCache.keys()) {
59
+ resolvedCache.delete(oldKey);
60
+ if (--drop <= 0)
61
+ break;
62
+ }
63
+ }
64
+ resolvedCache.set(key, value);
65
+ }
66
+ /** `GradientDirection` → expo-linear-gradient start/end points. */
67
+ const DIRECTION_POINTS = {
68
+ 'to-t': { start: { x: 0.5, y: 1 }, end: { x: 0.5, y: 0 } },
69
+ 'to-b': { start: { x: 0.5, y: 0 }, end: { x: 0.5, y: 1 } },
70
+ 'to-l': { start: { x: 1, y: 0.5 }, end: { x: 0, y: 0.5 } },
71
+ 'to-r': { start: { x: 0, y: 0.5 }, end: { x: 1, y: 0.5 } },
72
+ 'to-tl': { start: { x: 1, y: 1 }, end: { x: 0, y: 0 } },
73
+ 'to-tr': { start: { x: 0, y: 1 }, end: { x: 1, y: 0 } },
74
+ 'to-bl': { start: { x: 1, y: 0 }, end: { x: 0, y: 1 } },
75
+ 'to-br': { start: { x: 0, y: 0 }, end: { x: 1, y: 1 } },
76
+ unknown: { start: { x: 0, y: 0.5 }, end: { x: 1, y: 0.5 } },
77
+ };
78
+ /**
79
+ * Register one scheme's pre-merged molecules (atom-merged literal
80
+ * classNames). Merges onto any existing entries for the scheme.
81
+ * @param scheme Scheme name (or `'common'`).
82
+ * @param entries Normalized className → merged style object.
83
+ */
84
+ function registerMolecules(scheme, entries) {
85
+ molecules[scheme] = { ...molecules[scheme], ...entries };
86
+ registryVersion += 1;
87
+ }
88
+ /**
89
+ * Register the gradient atom map (atom name → role + resolved colour).
90
+ * @param map Atom name → gradient info.
91
+ */
92
+ function registerGradients(map) {
93
+ gradients = map;
94
+ registryVersion += 1;
95
+ }
96
+ /**
97
+ * Register the haptic atom map (atom name → request).
98
+ * @param map Atom name → haptic request.
99
+ */
100
+ function registerHaptics(map) {
101
+ haptics = map;
102
+ registryVersion += 1;
103
+ }
104
+ /**
105
+ * Per-state-object signature memo. `RnwindState` is created fresh (via the
106
+ * provider's `useMemo`) whenever any field changes, so its identity is a
107
+ * sound key — a new object means a new signature. Keyed weakly so states
108
+ * GC with their provider.
109
+ */
110
+ const stateSignatureCache = new WeakMap();
111
+ /**
112
+ * Cache key dimension for the reactive context — everything that can
113
+ * change a resolved style. Uses the breakpoint TIER (`activeBreakpoint`),
114
+ * NOT the raw `windowWidth`: two widths in the same tier gate `md:*` atoms
115
+ * identically, so they resolve the same. This collapses the window axis
116
+ * from "every pixel" to ~6 values, bounding the cache on resizable
117
+ * surfaces (web / desktop) without changing any result.
118
+ * @param state Rnwind context.
119
+ * @returns Compact signature string.
120
+ */
121
+ function stateSignature(state) {
122
+ const { insets } = state;
123
+ return `${state.scheme}|${insets.top},${insets.right},${insets.bottom},${insets.left}|${state.fontScale}|${state.activeBreakpoint}`;
124
+ }
125
+ /**
126
+ * Memoised {@link stateSignature} — one `WeakMap.get` on the hot path
127
+ * instead of rebuilding the template string every resolve.
128
+ * @param state Rnwind context.
129
+ * @returns Cached compact signature.
130
+ */
131
+ function stateSignatureCached(state) {
132
+ let signature = stateSignatureCache.get(state);
133
+ if (signature === undefined) {
134
+ signature = stateSignature(state);
135
+ stateSignatureCache.set(state, signature);
136
+ }
137
+ return signature;
138
+ }
139
+ /**
140
+ * Compact signature of the live interactive state for the cache key.
141
+ * @param interactState Active/focus flags, or undefined for the plain path.
142
+ * @returns Two-bit signature (`''` when no interactive state).
143
+ */
144
+ function interactSignature(interactState) {
145
+ if (!interactState)
146
+ return '';
147
+ const active = interactState.active ? 1 : 0;
148
+ const focus = interactState.focus ? 1 : 0;
149
+ return `${active}${focus}`;
150
+ }
151
+ /**
152
+ * Whether a token is a feature-ONLY utility (gradient stop/direction,
153
+ * haptic request, or text-truncate) that contributes NO RN `style`. These
154
+ * are folded in via {@link attachFeatures}, so they must be kept OUT of
155
+ * the `lookupCss` input — otherwise the atom resolver treats them as
156
+ * unknown style atoms and emits a spurious "unknown class" dev warning
157
+ * (e.g. for `active:haptic-rigid`).
158
+ * @param token Atom name.
159
+ * @returns True when the token carries no style.
160
+ */
161
+ function isFeatureOnlyToken(token) {
162
+ return Boolean(gradients[token]) || Boolean(haptics[token]) || truncateForToken(token) !== null;
163
+ }
164
+ /**
165
+ * Lifecycle trigger for a haptic atom from its variant prefix.
166
+ * @param token Atom name (maybe `active:`/`focus:`/`hover:` prefixed).
167
+ * @returns The trigger.
168
+ */
169
+ function hapticTriggerForToken(token) {
170
+ const colon = token.indexOf(':');
171
+ if (colon === -1)
172
+ return 'mount';
173
+ const prefix = token.slice(0, colon);
174
+ if (prefix === 'active')
175
+ return 'pressIn';
176
+ if (prefix === 'focus')
177
+ return 'focus';
178
+ if (prefix === 'hover')
179
+ return 'hover';
180
+ return 'mount';
181
+ }
182
+ /**
183
+ * Syntactic text-truncate directive for one atom.
184
+ * @param token Atom name.
185
+ * @returns Partial truncate props, or null.
186
+ */
187
+ function truncateForToken(token) {
188
+ if (token === 'truncate')
189
+ return { numberOfLines: 1, ellipsizeMode: 'tail' };
190
+ if (token === 'text-ellipsis')
191
+ return { ellipsizeMode: 'tail' };
192
+ if (token === 'text-clip')
193
+ return { ellipsizeMode: 'clip' };
194
+ if (token === 'line-clamp-none')
195
+ return { numberOfLines: 0 };
196
+ if (token.startsWith('line-clamp-')) {
197
+ const count = Number(token.slice('line-clamp-'.length));
198
+ if (Number.isInteger(count) && count >= 0)
199
+ return { numberOfLines: count };
200
+ }
201
+ return null;
202
+ }
203
+ /**
204
+ * Assemble gradient props from gradient roles present in the atom list.
205
+ * @param tokens Atom names.
206
+ * @returns `{colors, start, end}` or null when not a complete gradient.
207
+ */
208
+ function assembleGradient(tokens) {
209
+ let from;
210
+ let via;
211
+ let to;
212
+ let dir;
213
+ for (const token of tokens) {
214
+ const info = gradients[token];
215
+ if (!info)
216
+ continue;
217
+ switch (info.role) {
218
+ case 'from': {
219
+ from = info.color;
220
+ break;
221
+ }
222
+ case 'via': {
223
+ via = info.color;
224
+ break;
225
+ }
226
+ case 'to': {
227
+ to = info.color;
228
+ break;
229
+ }
230
+ default: {
231
+ ({ dir } = info);
232
+ }
233
+ }
234
+ }
235
+ if (dir === undefined)
236
+ return null;
237
+ const colors = [from, via, to].filter((color) => color !== undefined);
238
+ if (colors.length < 2)
239
+ return null;
240
+ const points = DIRECTION_POINTS[dir];
241
+ return { colors, start: points.start, end: points.end };
242
+ }
243
+ /**
244
+ * Fold every truncate directive across the atom list into one result —
245
+ * last token wins per prop (matches Tailwind last-wins).
246
+ * @param tokens Atom names.
247
+ * @returns Merged truncate props (empty when none apply).
248
+ */
249
+ function collectTruncate(tokens) {
250
+ const out = {};
251
+ for (const token of tokens) {
252
+ const truncate = truncateForToken(token);
253
+ if (!truncate)
254
+ continue;
255
+ if (truncate.numberOfLines !== undefined)
256
+ out.numberOfLines = truncate.numberOfLines;
257
+ if (truncate.ellipsizeMode !== undefined)
258
+ out.ellipsizeMode = truncate.ellipsizeMode;
259
+ }
260
+ return out;
261
+ }
262
+ /**
263
+ * Collect every haptic request present in the atom list, tagged with the
264
+ * lifecycle trigger its variant prefix implies.
265
+ * @param tokens Atom names.
266
+ * @returns Haptic request list, or undefined when none apply.
267
+ */
268
+ function collectHaptics(tokens) {
269
+ let collected;
270
+ for (const token of tokens) {
271
+ const request = haptics[token];
272
+ if (!request)
273
+ continue;
274
+ collected ??= [];
275
+ collected.push({ request, trigger: hapticTriggerForToken(token) });
276
+ }
277
+ return collected;
278
+ }
279
+ /**
280
+ * Scan tokens for the className-derived feature props (gradient,
281
+ * truncate, haptics) and fold them onto the base result.
282
+ * @param base Result carrying the resolved `style`.
283
+ * @param tokens Atom names.
284
+ * @returns The result with any feature props attached.
285
+ */
286
+ function attachFeatures(base, tokens) {
287
+ const { numberOfLines, ellipsizeMode } = collectTruncate(tokens);
288
+ const collected = collectHaptics(tokens);
289
+ const gradient = assembleGradient(tokens);
290
+ const result = { style: base.style };
291
+ if (gradient) {
292
+ result.colors = gradient.colors;
293
+ result.start = gradient.start;
294
+ result.end = gradient.end;
295
+ }
296
+ // `numberOfLines: 0` is kept (RN reads it as "unlimited"): `line-clamp-none`
297
+ // must be able to explicitly reset an earlier `line-clamp-N` on the same
298
+ // element — dropping the 0 would silently leave the prior limit in place.
299
+ if (numberOfLines !== undefined) {
300
+ result.numberOfLines = numberOfLines;
301
+ if (ellipsizeMode !== undefined)
302
+ result.ellipsizeMode = ellipsizeMode;
303
+ }
304
+ if (collected)
305
+ result.haptics = collected;
306
+ return result;
307
+ }
308
+ /**
309
+ * Flatten the per-atom style array into ONE object — a *runtime molecule*.
310
+ * RN flattens a style array left-to-right (later wins), which is exactly
311
+ * `Object.assign` semantics, so the merged object renders identically
312
+ * while giving dynamic (cva / clsx) classNames the same single-object
313
+ * shape a build-time molecule has. The caller caches the result per
314
+ * `(className · state)`, so the merge runs once per unique context.
315
+ * @param array Per-atom style array from `lookupCss`.
316
+ * @returns Single merged style object.
317
+ */
318
+ function mergeStyleArray(array) {
319
+ const out = {};
320
+ for (const entry of array)
321
+ if (entry && typeof entry === 'object')
322
+ Object.assign(out, entry);
323
+ return out;
324
+ }
325
+ /**
326
+ * Compose a resolved style with a caller-supplied inline style (user wins).
327
+ * @param style
328
+ * @param userStyle
329
+ */
330
+ function withUserStyle(style, userStyle) {
331
+ return Array.isArray(style) ? [...style, userStyle] : [style, userStyle];
332
+ }
333
+ /**
334
+ * Resolve a className against the reactive context into a style plus any
335
+ * className-derived props. Molecule-first (one lookup, by reference),
336
+ * atom-fallback for unseen / context-dependent strings, cached per
337
+ * `(className, state)`.
338
+ * @param className Raw className string.
339
+ * @param state Rnwind context from `useRnwind()`.
340
+ * @param userStyle Optional inline style appended last (wins).
341
+ * @param interactState Live active/focus flags (for `active:`/`focus:` atoms).
342
+ * @returns The resolved style + feature props.
343
+ */
344
+ function resolve(className, state, userStyle, interactState) {
345
+ const version = lookupCss.getStyleVersion() + registryVersion;
346
+ if (version !== cachedFor) {
347
+ resolvedCache.clear();
348
+ cachedFor = version;
349
+ }
350
+ if (className == null) {
351
+ return { style: userStyle === undefined || userStyle === null ? EMPTY : [userStyle] };
352
+ }
353
+ // Key on the RAW className so the hot (cache-hit) path skips normalize
354
+ // entirely — normalization only runs on a miss. The state signature is
355
+ // memoised per state object, so the hit path is one WeakMap.get + one
356
+ // string concat + one Map.get.
357
+ const key = `${className}@${stateSignatureCached(state)}@${interactSignature(interactState)}`;
358
+ const cached = resolvedCache.get(key);
359
+ if (cached !== undefined) {
360
+ return userStyle === undefined || userStyle === null ? cached : { ...cached, style: withUserStyle(cached.style, userStyle) };
361
+ }
362
+ const normalized = normalizeClassname.normalizeClassName(className);
363
+ if (normalized.length === 0) {
364
+ const empty = { style: EMPTY };
365
+ cacheResolved(key, empty);
366
+ return userStyle === undefined || userStyle === null ? empty : { style: [userStyle] };
367
+ }
368
+ // Molecules are static pre-merges; anything carrying `active:`/`focus:`
369
+ // is never registered as one, so the atom path handles interactive state.
370
+ const tokens = normalized.split(' ');
371
+ const molecule = interactState ? undefined : molecules[state.scheme]?.[normalized] ?? molecules[COMMON_SCHEME]?.[normalized];
372
+ // Feature-only tokens (gradient / haptic / truncate) carry no style — keep
373
+ // them out of the atom lookup so they don't warn as "unknown class". The
374
+ // atom array is merged into ONE object (a runtime molecule) so dynamic
375
+ // (cva / clsx) classNames get the same single-object shape as a build
376
+ // molecule; the cache below pins the context, so the merge is correct.
377
+ const style = molecule === undefined
378
+ ? mergeStyleArray(lookupCss.lookupCss(tokens.filter((token) => !isFeatureOnlyToken(token)).join(' '), state, undefined, interactState))
379
+ : molecule;
380
+ const base = attachFeatures({ style }, tokens);
381
+ cacheResolved(key, base);
382
+ return userStyle === undefined || userStyle === null ? base : { ...base, style: withUserStyle(base.style, userStyle) };
383
+ }
384
+ /** Test-only — clear the molecule / gradient / haptic registries + cache. */
385
+ function __resetResolveState() {
386
+ molecules = Object.create(null);
387
+ gradients = Object.create(null);
388
+ haptics = Object.create(null);
389
+ resolvedCache.clear();
390
+ registryVersion += 1;
391
+ cachedFor = -1;
392
+ }
393
+
394
+ exports.normalizeClassName = normalizeClassname.normalizeClassName;
395
+ exports.__resetResolveState = __resetResolveState;
396
+ exports.registerGradients = registerGradients;
397
+ exports.registerHaptics = registerHaptics;
398
+ exports.registerMolecules = registerMolecules;
399
+ exports.resolve = resolve;
400
+ //# sourceMappingURL=resolve.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.cjs","sources":["../../../../src/runtime/resolve.ts"],"sourcesContent":["import { getStyleVersion, lookupCss, type InteractState } from './lookup-css'\nimport type { RnwindState } from './components/rnwind-provider'\nimport { normalizeClassName } from '../core/normalize-classname'\nimport type { GradientAtomInfo, GradientDirection } from '../core/parser/gradient'\nimport type { HapticRequest, HapticTrigger } from '../core/parser/haptics'\n\n/**\n * Rich className resolver — the runtime heart of the wrap / `useCss`.\n *\n * Resolution order, per className string:\n * 1. **Molecule** — a build-time PRE-MERGED single style object for the\n * whole literal className (per scheme). One map lookup returns it by\n * reference: no array, no merge, no per-atom loop. The common case.\n * 2. **Atom fallback** — for a className the scanner never saw (a\n * runtime-built string like `` `${className} px-2` ``) OR one that\n * carries context-dependent atoms (`pt-safe`, `text-base`, `md:*`),\n * fall back to per-atom resolution via `lookupCss`, which folds in\n * insets / fontScale / breakpoint / scheme.\n *\n * Results are cached by `(normalized className, scheme, insets, fontScale,\n * breakpoint)` so repeated renders return the SAME reference until the\n * reactive context changes. Atoms / molecules / features all live in\n * build-time registries the generated `.rnwind/*.js` modules populate.\n */\n\n/** Always-loaded fallback scheme key. */\nconst COMMON_SCHEME = 'common'\n\n/** Empty style sentinel. */\nconst EMPTY: readonly unknown[] = []\n\n/** scheme → normalized className → pre-merged style object. */\nlet molecules: Record<string, Record<string, unknown>> = Object.create(null)\n/** atom name → gradient role + resolved colour. */\nlet gradients: Record<string, GradientAtomInfo> = Object.create(null)\n/** atom name (incl. `active:`/`focus:` prefix) → haptic request. */\nlet haptics: Record<string, HapticRequest> = Object.create(null)\n/** Bumps on any molecule/gradient/haptic registration. */\nlet registryVersion = 0\n\n/** Per-(className·state) resolved cache — strong references between context changes. */\nconst resolvedCache = new Map<string, ResolvedCss>()\n/** Version the cache was last valid for (`getStyleVersion()` + {@link registryVersion}). */\nlet cachedFor = -1\n\n/**\n * Hard ceiling on the resolved cache. The cache is pure memoisation, so\n * eviction only costs a re-resolve (sub-µs) — never correctness. Build\n * molecules are NOT in here; they live permanently in `molecules`.\n */\nconst MAX_RESOLVED_CACHE = 2048\n\n/**\n * Store a resolved result, bulk-evicting the OLDEST half when the cache\n * hits {@link MAX_RESOLVED_CACHE}. `Map` preserves insertion order, so the\n * first keys are the oldest. Bulk eviction keeps the hot (cache-hit) path\n * free of per-access LRU bookkeeping at the cost of an occasional small\n * recompute burst under sustained pressure (web / long sessions).\n * @param key Cache key.\n * @param value Resolved result to store.\n */\nfunction cacheResolved(key: string, value: ResolvedCss): void {\n if (resolvedCache.size >= MAX_RESOLVED_CACHE) {\n let drop = resolvedCache.size >> 1\n for (const oldKey of resolvedCache.keys()) {\n resolvedCache.delete(oldKey)\n if (--drop <= 0) break\n }\n }\n resolvedCache.set(key, value)\n}\n\n/** A unit-square gradient endpoint. */\ninterface GradientPoint {\n readonly x: number\n readonly y: number\n}\n\n/** Rich resolution: the RN `style` plus any className-derived props. */\nexport interface ResolvedCss {\n /** RN `style` value — a single molecule object (by ref) or an atom array. */\n readonly style: unknown\n /** Gradient stop colours (when the className is a complete gradient). */\n readonly colors?: readonly string[]\n /** Gradient start point. */\n readonly start?: GradientPoint\n /** Gradient end point. */\n readonly end?: GradientPoint\n /** Text truncation line count. */\n readonly numberOfLines?: number\n /** Text ellipsize mode. */\n readonly ellipsizeMode?: 'tail' | 'clip'\n /** Haptic requests present on the className, for the wrap to dispatch. */\n readonly haptics?: readonly { readonly request: HapticRequest; readonly trigger: HapticTrigger }[]\n}\n\n/** `GradientDirection` → expo-linear-gradient start/end points. */\nconst DIRECTION_POINTS: Record<GradientDirection, { start: GradientPoint; end: GradientPoint }> = {\n 'to-t': { start: { x: 0.5, y: 1 }, end: { x: 0.5, y: 0 } },\n 'to-b': { start: { x: 0.5, y: 0 }, end: { x: 0.5, y: 1 } },\n 'to-l': { start: { x: 1, y: 0.5 }, end: { x: 0, y: 0.5 } },\n 'to-r': { start: { x: 0, y: 0.5 }, end: { x: 1, y: 0.5 } },\n 'to-tl': { start: { x: 1, y: 1 }, end: { x: 0, y: 0 } },\n 'to-tr': { start: { x: 0, y: 1 }, end: { x: 1, y: 0 } },\n 'to-bl': { start: { x: 1, y: 0 }, end: { x: 0, y: 1 } },\n 'to-br': { start: { x: 0, y: 0 }, end: { x: 1, y: 1 } },\n unknown: { start: { x: 0, y: 0.5 }, end: { x: 1, y: 0.5 } },\n}\n\n/**\n * Register one scheme's pre-merged molecules (atom-merged literal\n * classNames). Merges onto any existing entries for the scheme.\n * @param scheme Scheme name (or `'common'`).\n * @param entries Normalized className → merged style object.\n */\nexport function registerMolecules(scheme: string, entries: Record<string, unknown>): void {\n molecules[scheme] = { ...molecules[scheme], ...entries }\n registryVersion += 1\n}\n\n/**\n * Register the gradient atom map (atom name → role + resolved colour).\n * @param map Atom name → gradient info.\n */\nexport function registerGradients(map: Record<string, GradientAtomInfo>): void {\n gradients = map\n registryVersion += 1\n}\n\n/**\n * Register the haptic atom map (atom name → request).\n * @param map Atom name → haptic request.\n */\nexport function registerHaptics(map: Record<string, HapticRequest>): void {\n haptics = map\n registryVersion += 1\n}\n\n\n\n/**\n * Per-state-object signature memo. `RnwindState` is created fresh (via the\n * provider's `useMemo`) whenever any field changes, so its identity is a\n * sound key — a new object means a new signature. Keyed weakly so states\n * GC with their provider.\n */\nconst stateSignatureCache = new WeakMap<RnwindState, string>()\n\n/**\n * Cache key dimension for the reactive context — everything that can\n * change a resolved style. Uses the breakpoint TIER (`activeBreakpoint`),\n * NOT the raw `windowWidth`: two widths in the same tier gate `md:*` atoms\n * identically, so they resolve the same. This collapses the window axis\n * from \"every pixel\" to ~6 values, bounding the cache on resizable\n * surfaces (web / desktop) without changing any result.\n * @param state Rnwind context.\n * @returns Compact signature string.\n */\nfunction stateSignature(state: RnwindState): string {\n const { insets } = state\n return `${state.scheme}|${insets.top},${insets.right},${insets.bottom},${insets.left}|${state.fontScale}|${state.activeBreakpoint}`\n}\n\n/**\n * Memoised {@link stateSignature} — one `WeakMap.get` on the hot path\n * instead of rebuilding the template string every resolve.\n * @param state Rnwind context.\n * @returns Cached compact signature.\n */\nfunction stateSignatureCached(state: RnwindState): string {\n let signature = stateSignatureCache.get(state)\n if (signature === undefined) {\n signature = stateSignature(state)\n stateSignatureCache.set(state, signature)\n }\n return signature\n}\n\n/**\n * Compact signature of the live interactive state for the cache key.\n * @param interactState Active/focus flags, or undefined for the plain path.\n * @returns Two-bit signature (`''` when no interactive state).\n */\nfunction interactSignature(interactState?: InteractState): string {\n if (!interactState) return ''\n const active = interactState.active ? 1 : 0\n const focus = interactState.focus ? 1 : 0\n return `${active}${focus}`\n}\n\n/**\n * Whether a token is a feature-ONLY utility (gradient stop/direction,\n * haptic request, or text-truncate) that contributes NO RN `style`. These\n * are folded in via {@link attachFeatures}, so they must be kept OUT of\n * the `lookupCss` input — otherwise the atom resolver treats them as\n * unknown style atoms and emits a spurious \"unknown class\" dev warning\n * (e.g. for `active:haptic-rigid`).\n * @param token Atom name.\n * @returns True when the token carries no style.\n */\nfunction isFeatureOnlyToken(token: string): boolean {\n return Boolean(gradients[token]) || Boolean(haptics[token]) || truncateForToken(token) !== null\n}\n\n/**\n * Lifecycle trigger for a haptic atom from its variant prefix.\n * @param token Atom name (maybe `active:`/`focus:`/`hover:` prefixed).\n * @returns The trigger.\n */\nfunction hapticTriggerForToken(token: string): HapticTrigger {\n const colon = token.indexOf(':')\n if (colon === -1) return 'mount'\n const prefix = token.slice(0, colon)\n if (prefix === 'active') return 'pressIn'\n if (prefix === 'focus') return 'focus'\n if (prefix === 'hover') return 'hover'\n return 'mount'\n}\n\n/**\n * Syntactic text-truncate directive for one atom.\n * @param token Atom name.\n * @returns Partial truncate props, or null.\n */\nfunction truncateForToken(token: string): { numberOfLines?: number; ellipsizeMode?: 'tail' | 'clip' } | null {\n if (token === 'truncate') return { numberOfLines: 1, ellipsizeMode: 'tail' }\n if (token === 'text-ellipsis') return { ellipsizeMode: 'tail' }\n if (token === 'text-clip') return { ellipsizeMode: 'clip' }\n if (token === 'line-clamp-none') return { numberOfLines: 0 }\n if (token.startsWith('line-clamp-')) {\n const count = Number(token.slice('line-clamp-'.length))\n if (Number.isInteger(count) && count >= 0) return { numberOfLines: count }\n }\n return null\n}\n\n/**\n * Assemble gradient props from gradient roles present in the atom list.\n * @param tokens Atom names.\n * @returns `{colors, start, end}` or null when not a complete gradient.\n */\nfunction assembleGradient(tokens: readonly string[]): { colors: string[]; start: GradientPoint; end: GradientPoint } | null {\n let from: string | undefined\n let via: string | undefined\n let to: string | undefined\n let dir: GradientDirection | undefined\n for (const token of tokens) {\n const info = gradients[token]\n if (!info) continue\n switch (info.role) {\n case 'from': {\n from = info.color\n break\n }\n case 'via': {\n via = info.color\n break\n }\n case 'to': {\n to = info.color\n break\n }\n default: {\n ;({ dir } = info)\n }\n }\n }\n if (dir === undefined) return null\n const colors = [from, via, to].filter((color): color is string => color !== undefined)\n if (colors.length < 2) return null\n const points = DIRECTION_POINTS[dir]\n return { colors, start: points.start, end: points.end }\n}\n\n/**\n * Fold every truncate directive across the atom list into one result —\n * last token wins per prop (matches Tailwind last-wins).\n * @param tokens Atom names.\n * @returns Merged truncate props (empty when none apply).\n */\nfunction collectTruncate(tokens: readonly string[]): { numberOfLines?: number; ellipsizeMode?: 'tail' | 'clip' } {\n const out: { numberOfLines?: number; ellipsizeMode?: 'tail' | 'clip' } = {}\n for (const token of tokens) {\n const truncate = truncateForToken(token)\n if (!truncate) continue\n if (truncate.numberOfLines !== undefined) out.numberOfLines = truncate.numberOfLines\n if (truncate.ellipsizeMode !== undefined) out.ellipsizeMode = truncate.ellipsizeMode\n }\n return out\n}\n\n/**\n * Collect every haptic request present in the atom list, tagged with the\n * lifecycle trigger its variant prefix implies.\n * @param tokens Atom names.\n * @returns Haptic request list, or undefined when none apply.\n */\nfunction collectHaptics(tokens: readonly string[]): { request: HapticRequest; trigger: HapticTrigger }[] | undefined {\n let collected: { request: HapticRequest; trigger: HapticTrigger }[] | undefined\n for (const token of tokens) {\n const request = haptics[token]\n if (!request) continue\n collected ??= []\n collected.push({ request, trigger: hapticTriggerForToken(token) })\n }\n return collected\n}\n\n/**\n * Scan tokens for the className-derived feature props (gradient,\n * truncate, haptics) and fold them onto the base result.\n * @param base Result carrying the resolved `style`.\n * @param tokens Atom names.\n * @returns The result with any feature props attached.\n */\nfunction attachFeatures(base: ResolvedCss, tokens: readonly string[]): ResolvedCss {\n const { numberOfLines, ellipsizeMode } = collectTruncate(tokens)\n const collected = collectHaptics(tokens)\n const gradient = assembleGradient(tokens)\n const result: Mutable<ResolvedCss> = { style: base.style }\n if (gradient) {\n result.colors = gradient.colors\n result.start = gradient.start\n result.end = gradient.end\n }\n // `numberOfLines: 0` is kept (RN reads it as \"unlimited\"): `line-clamp-none`\n // must be able to explicitly reset an earlier `line-clamp-N` on the same\n // element — dropping the 0 would silently leave the prior limit in place.\n if (numberOfLines !== undefined) {\n result.numberOfLines = numberOfLines\n if (ellipsizeMode !== undefined) result.ellipsizeMode = ellipsizeMode\n }\n if (collected) result.haptics = collected\n return result\n}\n\n/**\n * Flatten the per-atom style array into ONE object — a *runtime molecule*.\n * RN flattens a style array left-to-right (later wins), which is exactly\n * `Object.assign` semantics, so the merged object renders identically\n * while giving dynamic (cva / clsx) classNames the same single-object\n * shape a build-time molecule has. The caller caches the result per\n * `(className · state)`, so the merge runs once per unique context.\n * @param array Per-atom style array from `lookupCss`.\n * @returns Single merged style object.\n */\nfunction mergeStyleArray(array: readonly unknown[]): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const entry of array) if (entry && typeof entry === 'object') Object.assign(out, entry)\n return out\n}\n\n/**\n * Compose a resolved style with a caller-supplied inline style (user wins).\n * @param style\n * @param userStyle\n */\nfunction withUserStyle(style: unknown, userStyle: unknown): unknown {\n return Array.isArray(style) ? [...style, userStyle] : [style, userStyle]\n}\n\n/**\n * Resolve a className against the reactive context into a style plus any\n * className-derived props. Molecule-first (one lookup, by reference),\n * atom-fallback for unseen / context-dependent strings, cached per\n * `(className, state)`.\n * @param className Raw className string.\n * @param state Rnwind context from `useRnwind()`.\n * @param userStyle Optional inline style appended last (wins).\n * @param interactState Live active/focus flags (for `active:`/`focus:` atoms).\n * @returns The resolved style + feature props.\n */\nexport function resolve(\n className: string | null | undefined,\n state: RnwindState,\n userStyle?: unknown,\n interactState?: InteractState,\n): ResolvedCss {\n const version = getStyleVersion() + registryVersion\n if (version !== cachedFor) {\n resolvedCache.clear()\n cachedFor = version\n }\n if (className == null) {\n return { style: userStyle === undefined || userStyle === null ? EMPTY : [userStyle] }\n }\n // Key on the RAW className so the hot (cache-hit) path skips normalize\n // entirely — normalization only runs on a miss. The state signature is\n // memoised per state object, so the hit path is one WeakMap.get + one\n // string concat + one Map.get.\n const key = `${className}@${stateSignatureCached(state)}@${interactSignature(interactState)}`\n const cached = resolvedCache.get(key)\n if (cached !== undefined) {\n return userStyle === undefined || userStyle === null ? cached : { ...cached, style: withUserStyle(cached.style, userStyle) }\n }\n const normalized = normalizeClassName(className)\n if (normalized.length === 0) {\n const empty: ResolvedCss = { style: EMPTY }\n cacheResolved(key, empty)\n return userStyle === undefined || userStyle === null ? empty : { style: [userStyle] }\n }\n // Molecules are static pre-merges; anything carrying `active:`/`focus:`\n // is never registered as one, so the atom path handles interactive state.\n const tokens = normalized.split(' ')\n const molecule = interactState ? undefined : molecules[state.scheme]?.[normalized] ?? molecules[COMMON_SCHEME]?.[normalized]\n // Feature-only tokens (gradient / haptic / truncate) carry no style — keep\n // them out of the atom lookup so they don't warn as \"unknown class\". The\n // atom array is merged into ONE object (a runtime molecule) so dynamic\n // (cva / clsx) classNames get the same single-object shape as a build\n // molecule; the cache below pins the context, so the merge is correct.\n const style =\n molecule === undefined\n ? mergeStyleArray(lookupCss(tokens.filter((token) => !isFeatureOnlyToken(token)).join(' '), state, undefined, interactState))\n : molecule\n const base = attachFeatures({ style }, tokens)\n cacheResolved(key, base)\n return userStyle === undefined || userStyle === null ? base : { ...base, style: withUserStyle(base.style, userStyle) }\n}\n\n/** Local mutable view for building the frozen-shaped result. */\ntype Mutable<T> = { -readonly [K in keyof T]: T[K] }\n\n/** Test-only — clear the molecule / gradient / haptic registries + cache. */\nexport function __resetResolveState(): void {\n molecules = Object.create(null)\n gradients = Object.create(null)\n haptics = Object.create(null)\n resolvedCache.clear()\n registryVersion += 1\n cachedFor = -1\n}\n\n/** Test-only — current resolved-cache entry count + its hard ceiling. */\nexport function __resolveCacheStats(): { size: number; max: number } {\n return { size: resolvedCache.size, max: MAX_RESOLVED_CACHE }\n}\n\nexport {normalizeClassName} from '../core/normalize-classname'"],"names":["getStyleVersion","normalizeClassName","lookupCss"],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ import { type InteractState } from './lookup-css';
2
+ import type { RnwindState } from './components/rnwind-provider';
3
+ import type { GradientAtomInfo } from '../core/parser/gradient';
4
+ import type { HapticRequest, HapticTrigger } from '../core/parser/haptics';
5
+ /** A unit-square gradient endpoint. */
6
+ interface GradientPoint {
7
+ readonly x: number;
8
+ readonly y: number;
9
+ }
10
+ /** Rich resolution: the RN `style` plus any className-derived props. */
11
+ export interface ResolvedCss {
12
+ /** RN `style` value — a single molecule object (by ref) or an atom array. */
13
+ readonly style: unknown;
14
+ /** Gradient stop colours (when the className is a complete gradient). */
15
+ readonly colors?: readonly string[];
16
+ /** Gradient start point. */
17
+ readonly start?: GradientPoint;
18
+ /** Gradient end point. */
19
+ readonly end?: GradientPoint;
20
+ /** Text truncation line count. */
21
+ readonly numberOfLines?: number;
22
+ /** Text ellipsize mode. */
23
+ readonly ellipsizeMode?: 'tail' | 'clip';
24
+ /** Haptic requests present on the className, for the wrap to dispatch. */
25
+ readonly haptics?: readonly {
26
+ readonly request: HapticRequest;
27
+ readonly trigger: HapticTrigger;
28
+ }[];
29
+ }
30
+ /**
31
+ * Register one scheme's pre-merged molecules (atom-merged literal
32
+ * classNames). Merges onto any existing entries for the scheme.
33
+ * @param scheme Scheme name (or `'common'`).
34
+ * @param entries Normalized className → merged style object.
35
+ */
36
+ export declare function registerMolecules(scheme: string, entries: Record<string, unknown>): void;
37
+ /**
38
+ * Register the gradient atom map (atom name → role + resolved colour).
39
+ * @param map Atom name → gradient info.
40
+ */
41
+ export declare function registerGradients(map: Record<string, GradientAtomInfo>): void;
42
+ /**
43
+ * Register the haptic atom map (atom name → request).
44
+ * @param map Atom name → haptic request.
45
+ */
46
+ export declare function registerHaptics(map: Record<string, HapticRequest>): void;
47
+ /**
48
+ * Resolve a className against the reactive context into a style plus any
49
+ * className-derived props. Molecule-first (one lookup, by reference),
50
+ * atom-fallback for unseen / context-dependent strings, cached per
51
+ * `(className, state)`.
52
+ * @param className Raw className string.
53
+ * @param state Rnwind context from `useRnwind()`.
54
+ * @param userStyle Optional inline style appended last (wins).
55
+ * @param interactState Live active/focus flags (for `active:`/`focus:` atoms).
56
+ * @returns The resolved style + feature props.
57
+ */
58
+ export declare function resolve(className: string | null | undefined, state: RnwindState, userStyle?: unknown, interactState?: InteractState): ResolvedCss;
59
+ /** Test-only — clear the molecule / gradient / haptic registries + cache. */
60
+ export declare function __resetResolveState(): void;
61
+ /** Test-only — current resolved-cache entry count + its hard ceiling. */
62
+ export declare function __resolveCacheStats(): {
63
+ size: number;
64
+ max: number;
65
+ };
66
+ export { normalizeClassName } from '../core/normalize-classname';