rnwind 0.0.1 → 0.0.3

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 (330) hide show
  1. package/lib/cjs/core/parser/animation.cjs +427 -0
  2. package/lib/cjs/core/parser/animation.cjs.map +1 -0
  3. package/lib/cjs/core/parser/animation.d.ts +126 -0
  4. package/lib/cjs/core/parser/border-dispatcher.cjs +180 -0
  5. package/lib/cjs/core/parser/border-dispatcher.cjs.map +1 -0
  6. package/lib/cjs/core/parser/border-dispatcher.d.ts +15 -0
  7. package/lib/cjs/core/parser/case-convert.cjs +15 -0
  8. package/lib/cjs/core/parser/case-convert.cjs.map +1 -0
  9. package/lib/cjs/core/parser/case-convert.d.ts +6 -0
  10. package/lib/cjs/core/parser/color-properties-dispatcher.cjs +84 -0
  11. package/lib/cjs/core/parser/color-properties-dispatcher.cjs.map +1 -0
  12. package/lib/cjs/core/parser/color-properties-dispatcher.d.ts +19 -0
  13. package/lib/cjs/core/parser/color.cjs +193 -0
  14. package/lib/cjs/core/parser/color.cjs.map +1 -0
  15. package/lib/cjs/core/parser/color.d.ts +12 -0
  16. package/lib/cjs/core/parser/constants.cjs +21 -0
  17. package/lib/cjs/core/parser/constants.cjs.map +1 -0
  18. package/lib/cjs/core/parser/constants.d.ts +8 -0
  19. package/lib/cjs/core/parser/declaration.cjs +347 -0
  20. package/lib/cjs/core/parser/declaration.cjs.map +1 -0
  21. package/lib/cjs/core/parser/declaration.d.ts +15 -0
  22. package/lib/cjs/core/parser/gradient.cjs +132 -0
  23. package/lib/cjs/core/parser/gradient.cjs.map +1 -0
  24. package/lib/cjs/core/parser/gradient.d.ts +59 -0
  25. package/lib/cjs/core/parser/haptics.cjs +73 -0
  26. package/lib/cjs/core/parser/haptics.cjs.map +1 -0
  27. package/lib/cjs/core/parser/haptics.d.ts +47 -0
  28. package/lib/cjs/core/parser/index.d.ts +8 -0
  29. package/lib/cjs/core/parser/keyframes.cjs +95 -0
  30. package/lib/cjs/core/parser/keyframes.cjs.map +1 -0
  31. package/lib/cjs/core/parser/keyframes.d.ts +26 -0
  32. package/lib/cjs/core/parser/layout-dispatcher.cjs +120 -0
  33. package/lib/cjs/core/parser/layout-dispatcher.cjs.map +1 -0
  34. package/lib/cjs/core/parser/layout-dispatcher.d.ts +14 -0
  35. package/lib/cjs/core/parser/length.cjs +110 -0
  36. package/lib/cjs/core/parser/length.cjs.map +1 -0
  37. package/lib/cjs/core/parser/length.d.ts +51 -0
  38. package/lib/cjs/core/parser/motion-dispatcher.cjs +77 -0
  39. package/lib/cjs/core/parser/motion-dispatcher.cjs.map +1 -0
  40. package/lib/cjs/core/parser/motion-dispatcher.d.ts +11 -0
  41. package/lib/cjs/core/parser/property.cjs +22 -0
  42. package/lib/cjs/core/parser/property.cjs.map +1 -0
  43. package/lib/cjs/core/parser/property.d.ts +8 -0
  44. package/lib/cjs/core/parser/safe-area.cjs +404 -0
  45. package/lib/cjs/core/parser/safe-area.cjs.map +1 -0
  46. package/lib/cjs/core/parser/safe-area.d.ts +39 -0
  47. package/lib/cjs/core/parser/selector.cjs +22 -0
  48. package/lib/cjs/core/parser/selector.cjs.map +1 -0
  49. package/lib/cjs/core/parser/selector.d.ts +11 -0
  50. package/lib/cjs/core/parser/shorthand.cjs +188 -0
  51. package/lib/cjs/core/parser/shorthand.cjs.map +1 -0
  52. package/lib/cjs/core/parser/shorthand.d.ts +67 -0
  53. package/lib/cjs/core/parser/text-truncate.cjs +78 -0
  54. package/lib/cjs/core/parser/text-truncate.cjs.map +1 -0
  55. package/lib/cjs/core/parser/text-truncate.d.ts +44 -0
  56. package/lib/cjs/core/parser/theme-vars.cjs +467 -0
  57. package/lib/cjs/core/parser/theme-vars.cjs.map +1 -0
  58. package/lib/cjs/core/parser/theme-vars.d.ts +82 -0
  59. package/lib/cjs/core/parser/tokens.cjs +486 -0
  60. package/lib/cjs/core/parser/tokens.cjs.map +1 -0
  61. package/lib/cjs/core/parser/tokens.d.ts +45 -0
  62. package/lib/cjs/core/parser/transform.cjs +198 -0
  63. package/lib/cjs/core/parser/transform.cjs.map +1 -0
  64. package/lib/cjs/core/parser/transform.d.ts +36 -0
  65. package/lib/cjs/core/parser/tw-parser.cjs +1680 -0
  66. package/lib/cjs/core/parser/tw-parser.cjs.map +1 -0
  67. package/lib/cjs/core/parser/tw-parser.d.ts +210 -0
  68. package/lib/cjs/core/parser/types.d.ts +37 -0
  69. package/lib/cjs/core/parser/typography-dispatcher.cjs +108 -0
  70. package/lib/cjs/core/parser/typography-dispatcher.cjs.map +1 -0
  71. package/lib/cjs/core/parser/typography-dispatcher.d.ts +11 -0
  72. package/lib/cjs/core/parser/typography.cjs +97 -0
  73. package/lib/cjs/core/parser/typography.cjs.map +1 -0
  74. package/lib/cjs/core/parser/typography.d.ts +43 -0
  75. package/lib/cjs/core/style-builder/build-style.cjs +444 -0
  76. package/lib/cjs/core/style-builder/build-style.cjs.map +1 -0
  77. package/lib/cjs/core/style-builder/build-style.d.ts +54 -0
  78. package/lib/cjs/core/style-builder/index.d.ts +3 -0
  79. package/lib/cjs/core/style-builder/union-builder.cjs +326 -0
  80. package/lib/cjs/core/style-builder/union-builder.cjs.map +1 -0
  81. package/lib/cjs/core/style-builder/union-builder.d.ts +128 -0
  82. package/lib/cjs/core/types.d.ts +14 -0
  83. package/lib/cjs/metro/dts.cjs +127 -0
  84. package/lib/cjs/metro/dts.cjs.map +1 -0
  85. package/lib/cjs/metro/dts.d.ts +16 -0
  86. package/lib/cjs/metro/index.cjs +19 -0
  87. package/lib/cjs/metro/index.cjs.map +1 -0
  88. package/lib/cjs/metro/index.d.ts +9 -0
  89. package/lib/cjs/metro/resolver.cjs +47 -0
  90. package/lib/cjs/metro/resolver.cjs.map +1 -0
  91. package/lib/cjs/metro/resolver.d.ts +22 -0
  92. package/lib/cjs/metro/state.cjs +301 -0
  93. package/lib/cjs/metro/state.cjs.map +1 -0
  94. package/lib/cjs/metro/state.d.ts +88 -0
  95. package/lib/cjs/metro/transform-ast.cjs +1472 -0
  96. package/lib/cjs/metro/transform-ast.cjs.map +1 -0
  97. package/lib/cjs/metro/transform-ast.d.ts +88 -0
  98. package/lib/cjs/metro/transformer.cjs +372 -0
  99. package/lib/cjs/metro/transformer.cjs.map +1 -0
  100. package/lib/cjs/metro/transformer.d.ts +47 -0
  101. package/lib/cjs/metro/warn-unknown-classes.cjs +86 -0
  102. package/lib/cjs/metro/warn-unknown-classes.cjs.map +1 -0
  103. package/lib/cjs/metro/warn-unknown-classes.d.ts +21 -0
  104. package/lib/cjs/metro/with-config.cjs +196 -0
  105. package/lib/cjs/metro/with-config.cjs.map +1 -0
  106. package/lib/cjs/metro/with-config.d.ts +79 -0
  107. package/lib/cjs/runtime/chain-handlers.cjs +37 -0
  108. package/lib/cjs/runtime/chain-handlers.cjs.map +1 -0
  109. package/lib/cjs/runtime/chain-handlers.d.ts +33 -0
  110. package/lib/cjs/runtime/components/rnwind-provider.cjs +98 -0
  111. package/lib/cjs/runtime/components/rnwind-provider.cjs.map +1 -0
  112. package/lib/cjs/runtime/components/rnwind-provider.d.ts +84 -0
  113. package/lib/cjs/runtime/gradient-types.d.ts +58 -0
  114. package/lib/cjs/runtime/haptics.cjs +113 -0
  115. package/lib/cjs/runtime/haptics.cjs.map +1 -0
  116. package/lib/cjs/runtime/haptics.d.ts +48 -0
  117. package/lib/cjs/runtime/hooks/use-css.cjs +21 -0
  118. package/lib/cjs/runtime/hooks/use-css.cjs.map +1 -0
  119. package/lib/cjs/runtime/hooks/use-css.d.ts +11 -0
  120. package/lib/cjs/runtime/hooks/use-interact.cjs +46 -0
  121. package/lib/cjs/runtime/hooks/use-interact.cjs.map +1 -0
  122. package/lib/cjs/runtime/hooks/use-interact.d.ts +42 -0
  123. package/lib/cjs/runtime/hooks/use-scheme.cjs +68 -0
  124. package/lib/cjs/runtime/hooks/use-scheme.cjs.map +1 -0
  125. package/lib/cjs/runtime/hooks/use-scheme.d.ts +34 -0
  126. package/lib/cjs/runtime/index.cjs +45 -0
  127. package/lib/cjs/runtime/index.cjs.map +1 -0
  128. package/lib/cjs/runtime/index.d.ts +27 -0
  129. package/lib/cjs/runtime/interactive-box.cjs +35 -0
  130. package/lib/cjs/runtime/interactive-box.cjs.map +1 -0
  131. package/lib/cjs/runtime/interactive-box.d.ts +40 -0
  132. package/lib/cjs/runtime/lookup-css.cjs +542 -0
  133. package/lib/cjs/runtime/lookup-css.cjs.map +1 -0
  134. package/lib/cjs/runtime/lookup-css.d.ts +164 -0
  135. package/lib/cjs/runtime/types.d.ts +29 -0
  136. package/lib/cjs/testing/index.cjs +367 -0
  137. package/lib/cjs/testing/index.cjs.map +1 -0
  138. package/lib/cjs/testing/index.d.ts +145 -0
  139. package/lib/esm/core/parser/animation.d.ts +126 -0
  140. package/lib/esm/core/parser/animation.mjs +408 -0
  141. package/lib/esm/core/parser/animation.mjs.map +1 -0
  142. package/lib/esm/core/parser/border-dispatcher.d.ts +15 -0
  143. package/lib/esm/core/parser/border-dispatcher.mjs +178 -0
  144. package/lib/esm/core/parser/border-dispatcher.mjs.map +1 -0
  145. package/lib/esm/core/parser/case-convert.d.ts +6 -0
  146. package/lib/esm/core/parser/case-convert.mjs +13 -0
  147. package/lib/esm/core/parser/case-convert.mjs.map +1 -0
  148. package/lib/esm/core/parser/color-properties-dispatcher.d.ts +19 -0
  149. package/lib/esm/core/parser/color-properties-dispatcher.mjs +82 -0
  150. package/lib/esm/core/parser/color-properties-dispatcher.mjs.map +1 -0
  151. package/lib/esm/core/parser/color.d.ts +12 -0
  152. package/lib/esm/core/parser/color.mjs +191 -0
  153. package/lib/esm/core/parser/color.mjs.map +1 -0
  154. package/lib/esm/core/parser/constants.d.ts +8 -0
  155. package/lib/esm/core/parser/constants.mjs +13 -0
  156. package/lib/esm/core/parser/constants.mjs.map +1 -0
  157. package/lib/esm/core/parser/declaration.d.ts +15 -0
  158. package/lib/esm/core/parser/declaration.mjs +345 -0
  159. package/lib/esm/core/parser/declaration.mjs.map +1 -0
  160. package/lib/esm/core/parser/gradient.d.ts +59 -0
  161. package/lib/esm/core/parser/gradient.mjs +130 -0
  162. package/lib/esm/core/parser/gradient.mjs.map +1 -0
  163. package/lib/esm/core/parser/haptics.d.ts +47 -0
  164. package/lib/esm/core/parser/haptics.mjs +71 -0
  165. package/lib/esm/core/parser/haptics.mjs.map +1 -0
  166. package/lib/esm/core/parser/index.d.ts +8 -0
  167. package/lib/esm/core/parser/keyframes.d.ts +26 -0
  168. package/lib/esm/core/parser/keyframes.mjs +91 -0
  169. package/lib/esm/core/parser/keyframes.mjs.map +1 -0
  170. package/lib/esm/core/parser/layout-dispatcher.d.ts +14 -0
  171. package/lib/esm/core/parser/layout-dispatcher.mjs +118 -0
  172. package/lib/esm/core/parser/layout-dispatcher.mjs.map +1 -0
  173. package/lib/esm/core/parser/length.d.ts +51 -0
  174. package/lib/esm/core/parser/length.mjs +104 -0
  175. package/lib/esm/core/parser/length.mjs.map +1 -0
  176. package/lib/esm/core/parser/motion-dispatcher.d.ts +11 -0
  177. package/lib/esm/core/parser/motion-dispatcher.mjs +75 -0
  178. package/lib/esm/core/parser/motion-dispatcher.mjs.map +1 -0
  179. package/lib/esm/core/parser/property.d.ts +8 -0
  180. package/lib/esm/core/parser/property.mjs +20 -0
  181. package/lib/esm/core/parser/property.mjs.map +1 -0
  182. package/lib/esm/core/parser/safe-area.d.ts +39 -0
  183. package/lib/esm/core/parser/safe-area.mjs +402 -0
  184. package/lib/esm/core/parser/safe-area.mjs.map +1 -0
  185. package/lib/esm/core/parser/selector.d.ts +11 -0
  186. package/lib/esm/core/parser/selector.mjs +20 -0
  187. package/lib/esm/core/parser/selector.mjs.map +1 -0
  188. package/lib/esm/core/parser/shorthand.d.ts +67 -0
  189. package/lib/esm/core/parser/shorthand.mjs +180 -0
  190. package/lib/esm/core/parser/shorthand.mjs.map +1 -0
  191. package/lib/esm/core/parser/text-truncate.d.ts +44 -0
  192. package/lib/esm/core/parser/text-truncate.mjs +75 -0
  193. package/lib/esm/core/parser/text-truncate.mjs.map +1 -0
  194. package/lib/esm/core/parser/theme-vars.d.ts +82 -0
  195. package/lib/esm/core/parser/theme-vars.mjs +461 -0
  196. package/lib/esm/core/parser/theme-vars.mjs.map +1 -0
  197. package/lib/esm/core/parser/tokens.d.ts +45 -0
  198. package/lib/esm/core/parser/tokens.mjs +480 -0
  199. package/lib/esm/core/parser/tokens.mjs.map +1 -0
  200. package/lib/esm/core/parser/transform.d.ts +36 -0
  201. package/lib/esm/core/parser/transform.mjs +193 -0
  202. package/lib/esm/core/parser/transform.mjs.map +1 -0
  203. package/lib/esm/core/parser/tw-parser.d.ts +210 -0
  204. package/lib/esm/core/parser/tw-parser.mjs +1678 -0
  205. package/lib/esm/core/parser/tw-parser.mjs.map +1 -0
  206. package/lib/esm/core/parser/types.d.ts +37 -0
  207. package/lib/esm/core/parser/typography-dispatcher.d.ts +11 -0
  208. package/lib/esm/core/parser/typography-dispatcher.mjs +106 -0
  209. package/lib/esm/core/parser/typography-dispatcher.mjs.map +1 -0
  210. package/lib/esm/core/parser/typography.d.ts +43 -0
  211. package/lib/esm/core/parser/typography.mjs +91 -0
  212. package/lib/esm/core/parser/typography.mjs.map +1 -0
  213. package/lib/esm/core/style-builder/build-style.d.ts +54 -0
  214. package/lib/esm/core/style-builder/build-style.mjs +442 -0
  215. package/lib/esm/core/style-builder/build-style.mjs.map +1 -0
  216. package/lib/esm/core/style-builder/index.d.ts +3 -0
  217. package/lib/esm/core/style-builder/union-builder.d.ts +128 -0
  218. package/lib/esm/core/style-builder/union-builder.mjs +324 -0
  219. package/lib/esm/core/style-builder/union-builder.mjs.map +1 -0
  220. package/lib/esm/core/types.d.ts +14 -0
  221. package/lib/esm/metro/dts.d.ts +16 -0
  222. package/lib/esm/metro/dts.mjs +125 -0
  223. package/lib/esm/metro/dts.mjs.map +1 -0
  224. package/lib/esm/metro/index.d.ts +9 -0
  225. package/lib/esm/metro/index.mjs +6 -0
  226. package/lib/esm/metro/index.mjs.map +1 -0
  227. package/lib/esm/metro/resolver.d.ts +22 -0
  228. package/lib/esm/metro/resolver.mjs +43 -0
  229. package/lib/esm/metro/resolver.mjs.map +1 -0
  230. package/lib/esm/metro/state.d.ts +88 -0
  231. package/lib/esm/metro/state.mjs +291 -0
  232. package/lib/esm/metro/state.mjs.map +1 -0
  233. package/lib/esm/metro/transform-ast.d.ts +88 -0
  234. package/lib/esm/metro/transform-ast.mjs +1451 -0
  235. package/lib/esm/metro/transform-ast.mjs.map +1 -0
  236. package/lib/esm/metro/transformer.d.ts +47 -0
  237. package/lib/esm/metro/transformer.mjs +349 -0
  238. package/lib/esm/metro/transformer.mjs.map +1 -0
  239. package/lib/esm/metro/warn-unknown-classes.d.ts +21 -0
  240. package/lib/esm/metro/warn-unknown-classes.mjs +84 -0
  241. package/lib/esm/metro/warn-unknown-classes.mjs.map +1 -0
  242. package/lib/esm/metro/with-config.d.ts +79 -0
  243. package/lib/esm/metro/with-config.mjs +194 -0
  244. package/lib/esm/metro/with-config.mjs.map +1 -0
  245. package/lib/esm/runtime/chain-handlers.d.ts +33 -0
  246. package/lib/esm/runtime/chain-handlers.mjs +34 -0
  247. package/lib/esm/runtime/chain-handlers.mjs.map +1 -0
  248. package/lib/esm/runtime/components/rnwind-provider.d.ts +84 -0
  249. package/lib/esm/runtime/components/rnwind-provider.mjs +94 -0
  250. package/lib/esm/runtime/components/rnwind-provider.mjs.map +1 -0
  251. package/lib/esm/runtime/gradient-types.d.ts +58 -0
  252. package/lib/esm/runtime/haptics.d.ts +48 -0
  253. package/lib/esm/runtime/haptics.mjs +110 -0
  254. package/lib/esm/runtime/haptics.mjs.map +1 -0
  255. package/lib/esm/runtime/hooks/use-css.d.ts +11 -0
  256. package/lib/esm/runtime/hooks/use-css.mjs +19 -0
  257. package/lib/esm/runtime/hooks/use-css.mjs.map +1 -0
  258. package/lib/esm/runtime/hooks/use-interact.d.ts +42 -0
  259. package/lib/esm/runtime/hooks/use-interact.mjs +44 -0
  260. package/lib/esm/runtime/hooks/use-interact.mjs.map +1 -0
  261. package/lib/esm/runtime/hooks/use-scheme.d.ts +34 -0
  262. package/lib/esm/runtime/hooks/use-scheme.mjs +63 -0
  263. package/lib/esm/runtime/hooks/use-scheme.mjs.map +1 -0
  264. package/lib/esm/runtime/index.d.ts +27 -0
  265. package/lib/esm/runtime/index.mjs +18 -0
  266. package/lib/esm/runtime/index.mjs.map +1 -0
  267. package/lib/esm/runtime/interactive-box.d.ts +40 -0
  268. package/lib/esm/runtime/interactive-box.mjs +33 -0
  269. package/lib/esm/runtime/interactive-box.mjs.map +1 -0
  270. package/lib/esm/runtime/lookup-css.d.ts +164 -0
  271. package/lib/esm/runtime/lookup-css.mjs +531 -0
  272. package/lib/esm/runtime/lookup-css.mjs.map +1 -0
  273. package/lib/esm/runtime/types.d.ts +29 -0
  274. package/lib/esm/testing/index.d.ts +145 -0
  275. package/lib/esm/testing/index.mjs +344 -0
  276. package/lib/esm/testing/index.mjs.map +1 -0
  277. package/package.json +80 -13
  278. package/preset.css +1171 -0
  279. package/src/core/parser/animation.ts +404 -0
  280. package/src/core/parser/border-dispatcher.ts +176 -0
  281. package/src/core/parser/case-convert.ts +10 -0
  282. package/src/core/parser/color-properties-dispatcher.ts +78 -0
  283. package/src/core/parser/color.ts +191 -0
  284. package/src/core/parser/constants.ts +11 -0
  285. package/src/core/parser/declaration.ts +340 -0
  286. package/src/core/parser/gradient.ts +148 -0
  287. package/src/core/parser/haptics.ts +88 -0
  288. package/src/core/parser/index.ts +8 -0
  289. package/src/core/parser/keyframes.ts +84 -0
  290. package/src/core/parser/layout-dispatcher.ts +111 -0
  291. package/src/core/parser/length.ts +114 -0
  292. package/src/core/parser/motion-dispatcher.ts +89 -0
  293. package/src/core/parser/property.ts +15 -0
  294. package/src/core/parser/safe-area.ts +404 -0
  295. package/src/core/parser/selector.ts +17 -0
  296. package/src/core/parser/shorthand.ts +182 -0
  297. package/src/core/parser/text-truncate.ts +79 -0
  298. package/src/core/parser/theme-vars.ts +465 -0
  299. package/src/core/parser/tokens.ts +456 -0
  300. package/src/core/parser/transform.ts +195 -0
  301. package/src/core/parser/tw-parser.ts +1828 -0
  302. package/src/core/parser/types.ts +45 -0
  303. package/src/core/parser/typography-dispatcher.ts +97 -0
  304. package/src/core/parser/typography.ts +83 -0
  305. package/src/core/style-builder/build-style.ts +500 -0
  306. package/src/core/style-builder/index.ts +3 -0
  307. package/src/core/style-builder/union-builder.ts +328 -0
  308. package/src/core/types.ts +15 -0
  309. package/src/metro/dts.ts +128 -0
  310. package/src/metro/index.ts +9 -0
  311. package/src/metro/resolver.ts +42 -0
  312. package/src/metro/state.ts +305 -0
  313. package/src/metro/transform-ast.ts +1729 -0
  314. package/src/metro/transformer.ts +372 -0
  315. package/src/metro/warn-unknown-classes.ts +79 -0
  316. package/src/metro/with-config.ts +251 -0
  317. package/src/runtime/chain-handlers.ts +47 -0
  318. package/src/runtime/components/rnwind-provider.tsx +144 -0
  319. package/src/runtime/gradient-types.ts +60 -0
  320. package/src/runtime/haptics.ts +120 -0
  321. package/src/runtime/hooks/use-css.ts +16 -0
  322. package/src/runtime/hooks/use-interact.ts +65 -0
  323. package/src/runtime/hooks/use-scheme.ts +63 -0
  324. package/src/runtime/index.ts +54 -0
  325. package/src/runtime/interactive-box.tsx +57 -0
  326. package/src/runtime/lookup-css.ts +628 -0
  327. package/src/runtime/types.ts +32 -0
  328. package/src/testing/index.ts +507 -0
  329. package/src/types/tailwindcss-node.d.ts +33 -0
  330. package/src/index.ts +0 -1
@@ -0,0 +1,500 @@
1
+ import type { KeyframeBlock, RNStyle, SchemedStyle } from '../parser'
2
+
3
+ /** Match atom names like `border-hairline`, `h-hairline`, `border-t-hairline`, etc. */
4
+ const HAIRLINE_ATOM = /-hairline$/
5
+
6
+ /** Parser's synthetic "no variant" scheme — provides the canonical fallback. */
7
+ const BASE_SCHEME = 'base'
8
+
9
+ /** Runtime registry key for the always-loaded fallback scheme. */
10
+ const COMMON_SCHEME = 'common'
11
+
12
+ /** Sentinel key the parser sets on interactive (`active:`/`focus:`) atoms. */
13
+ const STATE_KEY = '__state'
14
+
15
+ /**
16
+ * Whether an atom is a `*-hairline` utility — its numeric value must be
17
+ * rewritten as `StyleSheet.hairlineWidth` at runtime.
18
+ * @param atomName Class name.
19
+ * @returns True when the atom is a hairline utility.
20
+ */
21
+ function isHairlineAtom(atomName: string): boolean {
22
+ return HAIRLINE_ATOM.test(atomName)
23
+ }
24
+
25
+ /**
26
+ * Whether an RN style object carries any own key. The parser emits
27
+ * empty `{}` for schemes an atom doesn't apply to; we treat those as
28
+ * "inherit canonical" and don't emit an entry for that scheme.
29
+ * @param style RN style object.
30
+ * @returns Whether the style has content.
31
+ */
32
+ function isNonEmptyStyle(style: RNStyle | undefined): style is RNStyle {
33
+ if (!style) return false
34
+ return Object.keys(style).length > 0
35
+ }
36
+
37
+ /**
38
+ * Iterate per-scheme entries from a parser-produced schemed bucket,
39
+ * skipping the reserved `__state` metadata key.
40
+ * @param schemed Parser output for one atom.
41
+ * @yields `[scheme, style]` pairs in object-key order.
42
+ */
43
+ function* iterScheme(schemed: SchemedStyle): IterableIterator<[string, RNStyle]> {
44
+ const raw = schemed as Readonly<Record<string, RNStyle | string>>
45
+ for (const key in raw) {
46
+ if (key === STATE_KEY) continue
47
+ yield [key, raw[key] as RNStyle]
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Pick the canonical style for an atom — the value that goes into
53
+ * `common.style.js`. Prefers the parser's `base` entry (the "default
54
+ * when no variant matches"); falls back to the first non-empty per-
55
+ * scheme entry when the atom has no explicit base.
56
+ * @param schemed Parser-produced per-scheme bucket.
57
+ * @returns Canonical style, or undefined when every scheme is empty.
58
+ */
59
+ function canonicalValue(schemed: SchemedStyle): RNStyle | undefined {
60
+ const baseEntry = (schemed as Readonly<Record<string, RNStyle>>)[BASE_SCHEME]
61
+ if (isNonEmptyStyle(baseEntry)) return baseEntry
62
+ for (const [, style] of iterScheme(schemed)) {
63
+ if (isNonEmptyStyle(style)) return style
64
+ }
65
+ return undefined
66
+ }
67
+
68
+ /**
69
+ * Collect every variant scheme name across the project's atoms. The
70
+ * synthetic `base` scheme is excluded — it's folded into the `common`
71
+ * output. Returns variants in sorted order for deterministic output.
72
+ * @param resolved Parser-produced atom map.
73
+ * @returns Variant scheme names (no `base`, no `common`).
74
+ */
75
+ function collectVariantSchemes(resolved: ReadonlyMap<string, SchemedStyle>): readonly string[] {
76
+ const set = new Set<string>()
77
+ for (const schemed of resolved.values()) {
78
+ for (const [scheme] of iterScheme(schemed)) {
79
+ if (scheme !== BASE_SCHEME) set.add(scheme)
80
+ }
81
+ }
82
+ return [...set].toSorted((a, b) => a.localeCompare(b))
83
+ }
84
+
85
+ /**
86
+ * Normalize a CSS keyframe selector to the percentage form Reanimated
87
+ * v4 keyframes objects use.
88
+ * @param offset Selector text (`'from'`, `'to'`, `'50%'`).
89
+ * @returns Percentage string.
90
+ */
91
+ function offsetToPercent(offset: string): string {
92
+ if (offset === 'from') return '0%'
93
+ if (offset === 'to') return '100%'
94
+ return offset
95
+ }
96
+
97
+ /**
98
+ * Replace a string `animationName` with the inline keyframes object
99
+ * Reanimated v4's CSS engine expects. Atoms whose `animationName`
100
+ * doesn't match any registered keyframe keep the original string.
101
+ * @param style RN style object (possibly carrying `animationName`).
102
+ * @param keyframes Keyframes available to this build.
103
+ * @returns Style with `animationName` inlined when matched.
104
+ */
105
+ function inlineAnimationName(style: RNStyle, keyframes: ReadonlyMap<string, KeyframeBlock>): RNStyle {
106
+ const name = style.animationName
107
+ if (typeof name !== 'string') return style
108
+ const block = keyframes.get(name)
109
+ if (!block) return style
110
+ const out: RNStyle = { ...style }
111
+ const inline: Record<string, Record<string, string | number>> = {}
112
+ for (const step of block.steps) inline[offsetToPercent(step.offset)] = step.style as Record<string, string | number>
113
+ out.animationName = inline as unknown as RNStyle[string]
114
+ return out
115
+ }
116
+
117
+ /**
118
+ * Convert any safe-area markers in the style into a precomputed spec
119
+ * envelope. Atoms with `__safe` markers become
120
+ * `{__safeStyle: [[cssKey, sideTag, or, offset], ...]}` — the runtime
121
+ * resolver reads `value.__safeStyle` as a single property access and
122
+ * resolves against live insets without walking the value's keys.
123
+ * @param style RN style as resolved by the parser.
124
+ * @returns Original style OR the safe-style envelope.
125
+ */
126
+ function envelopeSafeMarkers(
127
+ style: RNStyle,
128
+ ): RNStyle | { __safeStyle: readonly (readonly [string, string, number | undefined, number | undefined])[] } {
129
+ let specs: [string, string, number | undefined, number | undefined][] | null = null
130
+ for (const key of Object.keys(style)) {
131
+ const value = style[key]
132
+ if (typeof value !== 'object' || !value) continue
133
+ const marker = value as { __safe?: string; or?: number; offset?: number }
134
+ if (typeof marker.__safe !== 'string') continue
135
+ if (!specs) specs = []
136
+ specs.push([key, marker.__safe, marker.or, marker.offset])
137
+ }
138
+ if (!specs) return style
139
+ return { __safeStyle: specs }
140
+ }
141
+
142
+ /**
143
+ * Serialise a single atom's RN style to a JS object literal. Honors
144
+ * the `*-hairline` sentinel: numeric values get rewritten to
145
+ * `StyleSheet.hairlineWidth` so device-density differences land in the
146
+ * rendered border.
147
+ * @param atomName The atom's class name (used to detect hairline).
148
+ * @param style The atom's RN style object.
149
+ * @returns JS object-literal source.
150
+ */
151
+ function serializeStyle(atomName: string, style: RNStyle): string {
152
+ const json = JSON.stringify(style)
153
+ if (!isHairlineAtom(atomName)) return json
154
+ return json.replaceAll(/:(-?\d+(?:\.\d+)?)/g, ': StyleSheet.hairlineWidth')
155
+ }
156
+
157
+ /**
158
+ * Serialise an atom's resolved value — bare RN style object or an
159
+ * already-enveloped safe-style value.
160
+ * @param atomName Atom name (controls hairline rewrite).
161
+ * @param value Atom value (bare style or `{__safeStyle: spec[]}`).
162
+ * @returns JS source for the value.
163
+ */
164
+ function serializeAtomValue(atomName: string, value: unknown): string {
165
+ if (typeof value === 'object' && value !== null && '__safeStyle' in value) return JSON.stringify(value)
166
+ return serializeStyle(atomName, value as RNStyle)
167
+ }
168
+
169
+ /**
170
+ * Resolve + envelope + serialize an atom's value under one scheme.
171
+ * @param atomName Atom name.
172
+ * @param style Raw RN style for this scheme.
173
+ * @param keyframes Keyframes available to this build.
174
+ * @returns Serialized text ready to emit.
175
+ */
176
+ function prepareAtomValue(atomName: string, style: RNStyle, keyframes: ReadonlyMap<string, KeyframeBlock>): string {
177
+ const enveloped = envelopeSafeMarkers(inlineAnimationName(style, keyframes))
178
+ return serializeAtomValue(atomName, enveloped)
179
+ }
180
+
181
+ /**
182
+ * Per-file value deduplicator — interns each unique serialized atom
183
+ * value once and emits `const _s<N> = <value>` at module scope. Scheme
184
+ * entries reference the const instead of inlining the literal.
185
+ *
186
+ * Wins: (1) smaller bundle bytes for themes with many atoms sharing a
187
+ * style shape; (2) stable `===` inside one scheme so two atoms
188
+ * resolving to the same value yield the same object reference.
189
+ */
190
+ class ValueDeduper {
191
+ private readonly byText = new Map<string, string>()
192
+ private readonly decls: string[] = []
193
+
194
+ intern(serialized: string): string {
195
+ const existing = this.byText.get(serialized)
196
+ if (existing) return existing
197
+ const name = `_s${this.decls.length}`
198
+ this.decls.push(`const ${name} = ${serialized}`)
199
+ this.byText.set(serialized, name)
200
+ return name
201
+ }
202
+
203
+ get declarations(): readonly string[] {
204
+ return this.decls
205
+ }
206
+ }
207
+
208
+ /**
209
+ * Render one scheme file's source. `entries` is the list of atoms this
210
+ * scheme contributes — for `common` every atom's canonical value; for
211
+ * a variant only atoms whose value differs from canonical. Hairline
212
+ * atoms in this file trigger the `StyleSheet` import.
213
+ * @param schemeName Registry key (`'common'` or the variant name).
214
+ * @param entries `[atomName, serializedValue]` pairs to emit.
215
+ * @returns JS source text.
216
+ */
217
+ function renderSchemeFile(schemeName: string, entries: readonly (readonly [string, string])[]): string {
218
+ const needsStyleSheet = entries.some(([atom]) => isHairlineAtom(atom))
219
+ const deduper = new ValueDeduper()
220
+ const recordLines: string[] = []
221
+ for (const [atom, value] of entries) {
222
+ const ref = deduper.intern(value)
223
+ recordLines.push(` ${JSON.stringify(atom)}: ${ref},`)
224
+ }
225
+
226
+ const lines: string[] = []
227
+ if (needsStyleSheet) lines.push(`import { StyleSheet } from 'react-native'`)
228
+ lines.push(`import { registerAtoms } from 'rnwind'`, ``)
229
+ if (deduper.declarations.length > 0) {
230
+ for (const decl of deduper.declarations) lines.push(decl)
231
+ lines.push(``)
232
+ }
233
+ lines.push(`registerAtoms(${JSON.stringify(schemeName)}, {`, ...recordLines, `})`, ``)
234
+ return lines.join('\n')
235
+ }
236
+
237
+ /**
238
+ * Render the JS-object literal for the responsive-breakpoint table the
239
+ * runtime registers at manifest-load time. Sorted by ascending px
240
+ * threshold so the runtime can build a deterministic "tier index" for
241
+ * its style cache.
242
+ * @param breakpoints Breakpoint name → px-threshold map.
243
+ * @returns Object-literal source (`{}` when empty).
244
+ */
245
+ function serializeBreakpoints(breakpoints: ReadonlyMap<string, number>): string {
246
+ if (breakpoints.size === 0) return '{}'
247
+ const entries = [...breakpoints].toSorted((a, b) => a[1] - b[1] || a[0].localeCompare(b[0]))
248
+ const inner = entries.map(([name, px]) => `${JSON.stringify(name)}: ${px}`).join(', ')
249
+ return `{ ${inner} }`
250
+ }
251
+
252
+ /**
253
+ * Render the manifest module. Eager-imports `common.style.js` (every
254
+ * rewritten source file pulls this via a transitive side-effect
255
+ * import), registers the responsive-breakpoint table once, and lazy-
256
+ * requires every variant scheme's file through an inline require —
257
+ * first call in `ensureSchemeLoaded(name)` triggers the scheme
258
+ * module's evaluation; Metro's module cache makes subsequent calls
259
+ * no-ops.
260
+ * @param variants Variant scheme names (no `base`, no `common`).
261
+ * @param breakpoints Responsive breakpoint name → px-threshold map.
262
+ * @returns JS source text.
263
+ */
264
+ function renderManifest(variants: readonly string[], breakpoints: ReadonlyMap<string, number>): string {
265
+ const lines: string[] = [
266
+ `import { registerSchemeLoader, registerBreakpoints } from 'rnwind'`,
267
+ `import './common.style'`,
268
+ ``,
269
+ `registerBreakpoints(${serializeBreakpoints(breakpoints)})`,
270
+ ``,
271
+ ]
272
+ if (variants.length === 0) {
273
+ lines.push(`function ensureSchemeLoaded(_name) {}`, ``, `registerSchemeLoader(ensureSchemeLoaded)`, ``, `export { ensureSchemeLoaded }`, ``)
274
+ return lines.join('\n')
275
+ }
276
+ lines.push(`const LOADERS = {`)
277
+ for (const variant of variants) {
278
+ lines.push(` ${JSON.stringify(variant)}: () => require(${JSON.stringify(`./${variant}.style`)}),`)
279
+ }
280
+ lines.push(`}`, ``, `function ensureSchemeLoaded(name) {`, ` const loader = LOADERS[name]`, ` if (loader) loader()`, `}`, ``, `registerSchemeLoader(ensureSchemeLoaded)`, ``, `export { ensureSchemeLoaded }`, ``)
281
+ return lines.join('\n')
282
+ }
283
+
284
+ /** Output of one build pass — one source per scheme plus the manifest. */
285
+ export interface BuildSchemeSourcesOutput {
286
+ /** `<schemeName>.style.js` source per scheme. Always contains `common`. */
287
+ readonly schemeSources: Readonly<Record<string, string>>
288
+ /** Manifest module source (`schemes.js`). */
289
+ readonly manifestSource: string
290
+ /** Variant scheme names this build covers (sorted; excludes `common`). */
291
+ readonly variants: readonly string[]
292
+ /** Number of `prepareAtomValue` / JSON.stringify passes (cache MISSES) this call did — test telemetry. */
293
+ readonly serializedMisses: number
294
+ }
295
+
296
+ /**
297
+ * Per-atom cached serialized value. Canonical (common) string plus a
298
+ * map of variant → own-serialized-string. `styleRef` is an identity
299
+ * guard against the resolved SchemedStyle — when callers replace an
300
+ * atom's value the ref diverges and the cache rebuilds that entry.
301
+ */
302
+ export interface AtomSerializedEntry {
303
+ styleRef: SchemedStyle
304
+ canonical: string
305
+ variants: Map<string, string>
306
+ }
307
+
308
+ /** Cache UnionBuilder owns across repeated writeSchemes calls. */
309
+ export type AtomSerializedCache = Map<string, AtomSerializedEntry>
310
+
311
+ /**
312
+ * Pre-serialize every non-empty variant value, reusing the per-atom
313
+ * cache where present. Result drives both the scheme-uniform check
314
+ * AND the per-variant emission loop downstream.
315
+ * @param atom Atom name.
316
+ * @param schemed Parser-produced schemed bucket.
317
+ * @param variants Variant scheme names in deterministic order.
318
+ * @param keyframes Keyframes available to inline.
319
+ * @param cached Cached entry for this atom (when ref-stable).
320
+ * @returns variantName → serialized text.
321
+ */
322
+ function buildVariantTexts(
323
+ atom: string,
324
+ schemed: SchemedStyle,
325
+ variants: readonly string[],
326
+ keyframes: ReadonlyMap<string, KeyframeBlock>,
327
+ cached: AtomSerializedEntry | undefined,
328
+ ): Map<string, string> {
329
+ const out = new Map<string, string>()
330
+ for (const variant of variants) {
331
+ const own = (schemed as Readonly<Record<string, RNStyle>>)[variant]
332
+ if (!isNonEmptyStyle(own)) continue
333
+ const text = cached?.variants.get(variant) ?? prepareAtomValue(atom, own, keyframes)
334
+ out.set(variant, text)
335
+ }
336
+ return out
337
+ }
338
+
339
+ /**
340
+ * Decide whether a (no-base) atom should be promoted to common because
341
+ * every declared variant resolves to the same value. This is the
342
+ * scheme-uniform case: `flex`, `p-4`, `absolute` all carry no theme
343
+ * variables, so Phase-1 fills every variant bucket identically and
344
+ * leaves `base` empty — without this collapse they'd be duplicated
345
+ * across every scheme file.
346
+ *
347
+ * The variant-prefix check is what keeps a real scheme-gated atom
348
+ * (`dark:bg-indigo-800`) out of common in a single-variant project
349
+ * (where its 1 bucket would otherwise look "uniform" by definition).
350
+ * @param atom Atom name (checked for `<variant>:` prefix).
351
+ * @param variants Declared variant scheme names.
352
+ * @param variantTexts Serialized variant values.
353
+ * @param canonicalText Serialized canonical (common) value.
354
+ * @returns Whether the atom is uniform across every declared variant.
355
+ */
356
+ function isSchemeUniform(
357
+ atom: string,
358
+ variants: readonly string[],
359
+ variantTexts: ReadonlyMap<string, string>,
360
+ canonicalText: string,
361
+ ): boolean {
362
+ if (variants.length === 0 || variantTexts.size !== variants.length) return false
363
+ if (variants.some((variant) => atom.startsWith(`${variant}:`))) return false
364
+ for (const text of variantTexts.values()) {
365
+ if (text !== canonicalText) return false
366
+ }
367
+ return true
368
+ }
369
+
370
+ /**
371
+ * Serialize one atom's canonical + variant-diff entries, honouring the
372
+ * per-atom cache. Returns the number of cache MISSES this atom incurred
373
+ * (0 when canonical was cached AND every needed variant was cached;
374
+ * 1 when anything had to be re-stringified).
375
+ *
376
+ * Three paths gated on whether the parser produced a non-empty `base`
377
+ * bucket and whether the variants converge:
378
+ * - **Themed atom (base present)**: canonical goes to `common`, each
379
+ * variant whose own value diverges from canonical writes the diff
380
+ * into its own scheme file. `lookupAtom` finds the variant's
381
+ * override or falls through to common.
382
+ * - **Scheme-uniform atom (base empty, every variant identical)**:
383
+ * promoted to `common` once — the parser's Phase-1 fills every
384
+ * variant bucket with the same value for utilities like `flex` /
385
+ * `p-4` / `absolute` that don't reference theme variables.
386
+ * - **Scheme-gated atom (base empty, prefixed name like `dark:foo`,
387
+ * or variants diverge)**: each populated variant writes the value
388
+ * into its own scheme file directly; common stays empty so the
389
+ * runtime fallback can't leak the variant style into other schemes.
390
+ * @param atom Atom name.
391
+ * @param schemed Parser-produced schemed bucket for the atom.
392
+ * @param canonical Canonical RN style for `common`.
393
+ * @param variants Variant scheme names in deterministic order.
394
+ * @param keyframes Keyframes available to inline.
395
+ * @param commonEntries Mutable collector for `common`'s `[atom, text]` pairs.
396
+ * @param variantEntries Mutable collector keyed by variant name.
397
+ * @param cache Optional shared serialized-value cache.
398
+ * @returns Number of JSON.stringify passes triggered for this atom.
399
+ */
400
+ function collectAtomEntries(
401
+ atom: string,
402
+ schemed: SchemedStyle,
403
+ canonical: RNStyle,
404
+ variants: readonly string[],
405
+ keyframes: ReadonlyMap<string, KeyframeBlock>,
406
+ commonEntries: (readonly [string, string])[],
407
+ variantEntries: Record<string, (readonly [string, string])[]>,
408
+ cache?: AtomSerializedCache,
409
+ ): number {
410
+ const cached = cache?.get(atom)
411
+ const hit = cached?.styleRef === schemed
412
+ const baseEntry = (schemed as Readonly<Record<string, RNStyle>>)[BASE_SCHEME]
413
+ const hasBase = isNonEmptyStyle(baseEntry)
414
+ const canonicalText = hit ? cached.canonical : prepareAtomValue(atom, canonical, keyframes)
415
+ const variantTexts = buildVariantTexts(atom, schemed, variants, keyframes, hit ? cached : undefined)
416
+ const goesToCommon = hasBase || isSchemeUniform(atom, variants, variantTexts, canonicalText)
417
+
418
+ if (goesToCommon) commonEntries.push([atom, canonicalText])
419
+
420
+ const entry: AtomSerializedEntry = hit
421
+ ? cached
422
+ : { styleRef: schemed, canonical: canonicalText, variants: new Map(variantTexts) }
423
+ if (!hit) cache?.set(atom, entry)
424
+
425
+ for (const variant of variants) {
426
+ const ownText = variantTexts.get(variant)
427
+ if (ownText === undefined) continue
428
+ if (goesToCommon && ownText === canonicalText) continue
429
+ variantEntries[variant].push([atom, ownText])
430
+ }
431
+ return hit ? 0 : 1
432
+ }
433
+
434
+ /** Empty fallback when the caller didn't supply breakpoints (legacy callers, tests). */
435
+ const EMPTY_BREAKPOINTS: ReadonlyMap<string, number> = new Map()
436
+
437
+ /**
438
+ * Build the per-scheme style files + manifest source.
439
+ *
440
+ * Dedup rule (the thing that shrinks scheme files to their diff):
441
+ * - Every atom's canonical value goes into `common.style.js`.
442
+ * - Each variant's file emits an entry for an atom ONLY when the
443
+ * variant's own resolved value differs from canonical. When the
444
+ * variant inherits (parser emits an empty `{}` for that scheme) or
445
+ * the variant's resolved value serializes identically to canonical,
446
+ * the atom is omitted — at runtime the lookup falls through via
447
+ * `cache.atoms[scheme]?.[atom] ?? cache.atoms.common[atom]`.
448
+ *
449
+ * Keyframes are inlined directly into atom values via `animationName`
450
+ * ({@link inlineAnimationName}). Safe-area markers get pre-enveloped
451
+ * via {@link envelopeSafeMarkers}. Hairline utilities stay bound to
452
+ * `StyleSheet.hairlineWidth` at runtime.
453
+ * @param atomNames All atom names (sorted).
454
+ * @param resolved Per-atom schemed styles from the parser.
455
+ * @param keyframes Keyframe blocks referenced by any atom.
456
+ * @param cache Optional shared serialized-value cache.
457
+ * @param breakpoints Responsive breakpoint name → px-threshold map. The
458
+ * manifest emits `registerBreakpoints({...})` so the runtime can gate
459
+ * `md:*` / `lg:*` atoms on `windowWidth`. Optional — empty when the
460
+ * theme declares no breakpoints (legacy/test callers).
461
+ * @returns Per-scheme sources, manifest source, variant list.
462
+ */
463
+ export function buildSchemeSources(
464
+ atomNames: readonly string[],
465
+ resolved: ReadonlyMap<string, SchemedStyle>,
466
+ keyframes: ReadonlyMap<string, KeyframeBlock>,
467
+ cache?: AtomSerializedCache,
468
+ breakpoints: ReadonlyMap<string, number> = EMPTY_BREAKPOINTS,
469
+ ): BuildSchemeSourcesOutput {
470
+ const variants = collectVariantSchemes(resolved)
471
+ const commonEntries: (readonly [string, string])[] = []
472
+ const variantEntries: Record<string, (readonly [string, string])[]> = {}
473
+ for (const variant of variants) variantEntries[variant] = []
474
+ let misses = 0
475
+
476
+ for (const atom of atomNames) {
477
+ const schemed = resolved.get(atom)
478
+ if (!schemed) continue
479
+ const canonical = canonicalValue(schemed)
480
+ if (!canonical) continue
481
+ misses += collectAtomEntries(atom, schemed, canonical, variants, keyframes, commonEntries, variantEntries, cache)
482
+ }
483
+
484
+ const schemeSources: Record<string, string> = {
485
+ [COMMON_SCHEME]: renderSchemeFile(COMMON_SCHEME, commonEntries),
486
+ }
487
+ for (const variant of variants) {
488
+ schemeSources[variant] = renderSchemeFile(variant, variantEntries[variant])
489
+ }
490
+
491
+ return {
492
+ schemeSources,
493
+ manifestSource: renderManifest(variants, breakpoints),
494
+ variants,
495
+ serializedMisses: misses,
496
+ }
497
+ }
498
+
499
+ /** Registry key the runtime uses for the always-loaded fallback. */
500
+ export const COMMON_SCHEME_NAME: string = COMMON_SCHEME
@@ -0,0 +1,3 @@
1
+ export { UnionBuilder } from './union-builder'
2
+ export { buildSchemeSources, COMMON_SCHEME_NAME } from './build-style'
3
+ export type { BuildSchemeSourcesOutput } from './build-style'