@jesscss/core 2.0.0-alpha.4 → 2.0.0-alpha.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 (637) hide show
  1. package/lib/index.cjs +20159 -0
  2. package/lib/index.d.cts +5993 -0
  3. package/lib/index.d.cts.map +1 -0
  4. package/lib/index.d.ts +5992 -21
  5. package/lib/index.d.ts.map +1 -1
  6. package/lib/index.js +19926 -22
  7. package/lib/index.js.map +1 -1
  8. package/package.json +15 -14
  9. package/src/__tests__/define-function-record.test.ts +58 -0
  10. package/src/__tests__/define-function-simple.test.ts +55 -0
  11. package/src/__tests__/define-function-split-sequence.test.ts +547 -0
  12. package/src/__tests__/define-function-type-parity.test.ts +9 -0
  13. package/src/__tests__/define-function.test.ts +763 -0
  14. package/src/__tests__/num-operations.test.ts +91 -0
  15. package/src/__tests__/safe-parse.test.ts +374 -0
  16. package/src/context.ts +896 -0
  17. package/src/conversions.ts +282 -0
  18. package/src/debug-log.ts +29 -0
  19. package/src/define-function.ts +1006 -0
  20. package/src/deprecation.ts +67 -0
  21. package/src/globals.d.ts +26 -0
  22. package/src/index.ts +31 -0
  23. package/src/jess-error.ts +773 -0
  24. package/src/logger/deprecation-processing.ts +109 -0
  25. package/src/logger.ts +31 -0
  26. package/src/plugin.ts +292 -0
  27. package/src/tree/LOOKUP_CHAINS.md +35 -0
  28. package/src/tree/README.md +18 -0
  29. package/src/tree/__tests__/__snapshots__/extend-eval-integration.test.ts.snap +1455 -0
  30. package/src/tree/__tests__/ampersand.test.ts +382 -0
  31. package/src/tree/__tests__/at-rule.test.ts +2047 -0
  32. package/src/tree/__tests__/basic-render.test.ts +212 -0
  33. package/src/tree/__tests__/block.test.ts +40 -0
  34. package/src/tree/__tests__/call.test.ts +346 -0
  35. package/src/tree/__tests__/color.test.ts +537 -0
  36. package/src/tree/__tests__/condition.test.ts +186 -0
  37. package/src/tree/__tests__/control.test.ts +564 -0
  38. package/src/tree/__tests__/declaration.test.ts +253 -0
  39. package/src/tree/__tests__/dependency-graph.test.ts +177 -0
  40. package/src/tree/__tests__/detached-rulesets.test.ts +213 -0
  41. package/src/tree/__tests__/dimension.test.ts +236 -0
  42. package/src/tree/__tests__/expression.test.ts +73 -0
  43. package/src/tree/__tests__/ext-node.test.ts +31 -0
  44. package/src/tree/__tests__/extend-eval-integration.test.ts +1033 -0
  45. package/src/tree/__tests__/extend-import-style.test.ts +929 -0
  46. package/src/tree/__tests__/extend-less-fixtures.test.ts +851 -0
  47. package/src/tree/__tests__/extend-list.test.ts +31 -0
  48. package/src/tree/__tests__/extend-roots.test.ts +1045 -0
  49. package/src/tree/__tests__/extend-rules.test.ts +740 -0
  50. package/src/tree/__tests__/func.test.ts +171 -0
  51. package/src/tree/__tests__/import-js.test.ts +33 -0
  52. package/src/tree/__tests__/import-style-test-helpers.ts +56 -0
  53. package/src/tree/__tests__/import-style.test.ts +1967 -0
  54. package/src/tree/__tests__/interpolated-reference.test.ts +44 -0
  55. package/src/tree/__tests__/interpolated.test.ts +41 -0
  56. package/src/tree/__tests__/list.test.ts +177 -0
  57. package/src/tree/__tests__/log.test.ts +83 -0
  58. package/src/tree/__tests__/mixin-recursion.test.ts +639 -0
  59. package/src/tree/__tests__/mixin.test.ts +2171 -0
  60. package/src/tree/__tests__/negative.test.ts +45 -0
  61. package/src/tree/__tests__/nesting-collapse.test.ts +519 -0
  62. package/src/tree/__tests__/node-flags-perf.test.ts +195 -0
  63. package/src/tree/__tests__/node-flags.test.ts +410 -0
  64. package/src/tree/__tests__/node-graph.test.ts +598 -0
  65. package/src/tree/__tests__/node-mutation.test.ts +182 -0
  66. package/src/tree/__tests__/operation.test.ts +18 -0
  67. package/src/tree/__tests__/paren.test.ts +90 -0
  68. package/src/tree/__tests__/preserve-mode-output.test.ts +50 -0
  69. package/src/tree/__tests__/quoted.test.ts +72 -0
  70. package/src/tree/__tests__/range.test.ts +59 -0
  71. package/src/tree/__tests__/reference.test.ts +743 -0
  72. package/src/tree/__tests__/rest.test.ts +29 -0
  73. package/src/tree/__tests__/rules-raw.test.ts +14 -0
  74. package/src/tree/__tests__/rules.test.ts +1271 -0
  75. package/src/tree/__tests__/ruleset.test.ts +597 -0
  76. package/src/tree/__tests__/selector-attr.test.ts +50 -0
  77. package/src/tree/__tests__/selector-basic.test.ts +44 -0
  78. package/src/tree/__tests__/selector-capture.test.ts +22 -0
  79. package/src/tree/__tests__/selector-complex.test.ts +120 -0
  80. package/src/tree/__tests__/selector-compound.test.ts +74 -0
  81. package/src/tree/__tests__/selector-interpolated.test.ts +50 -0
  82. package/src/tree/__tests__/selector-list.test.ts +59 -0
  83. package/src/tree/__tests__/selector-pseudo.test.ts +23 -0
  84. package/src/tree/__tests__/selector.test.ts +182 -0
  85. package/src/tree/__tests__/sequence.test.ts +226 -0
  86. package/src/tree/__tests__/serialize-types.test.ts +529 -0
  87. package/src/tree/__tests__/spaced.test.ts +8 -0
  88. package/src/tree/__tests__/url.test.ts +72 -0
  89. package/src/tree/__tests__/var-declaration.test.ts +90 -0
  90. package/src/tree/ampersand.ts +538 -0
  91. package/src/tree/any.ts +169 -0
  92. package/src/tree/at-rule.ts +760 -0
  93. package/src/tree/block.ts +72 -0
  94. package/src/tree/bool.ts +46 -0
  95. package/src/tree/call.ts +593 -0
  96. package/src/tree/collection.ts +52 -0
  97. package/src/tree/color.ts +629 -0
  98. package/src/tree/combinator.ts +30 -0
  99. package/src/tree/comment.ts +36 -0
  100. package/src/tree/condition.ts +194 -0
  101. package/src/tree/control.ts +452 -0
  102. package/src/tree/declaration-custom.ts +56 -0
  103. package/src/tree/declaration-var.ts +87 -0
  104. package/src/tree/declaration.ts +742 -0
  105. package/src/tree/default-guard.ts +35 -0
  106. package/src/tree/dimension.ts +392 -0
  107. package/src/tree/expression.ts +97 -0
  108. package/src/tree/extend-list.ts +51 -0
  109. package/src/tree/extend.ts +391 -0
  110. package/src/tree/function.ts +254 -0
  111. package/src/tree/import-js.ts +130 -0
  112. package/src/tree/import-style.ts +875 -0
  113. package/{lib/tree/index.js → src/tree/index.ts} +49 -22
  114. package/src/tree/interpolated.ts +346 -0
  115. package/src/tree/js-array.ts +21 -0
  116. package/src/tree/js-expr.ts +50 -0
  117. package/src/tree/js-function.ts +31 -0
  118. package/src/tree/js-object.ts +22 -0
  119. package/src/tree/list.ts +415 -0
  120. package/src/tree/log.ts +89 -0
  121. package/src/tree/mixin.ts +331 -0
  122. package/src/tree/negative.ts +58 -0
  123. package/src/tree/nil.ts +57 -0
  124. package/src/tree/node-base.ts +1716 -0
  125. package/src/tree/node-type.ts +122 -0
  126. package/src/tree/node.ts +118 -0
  127. package/src/tree/number.ts +54 -0
  128. package/src/tree/operation.ts +187 -0
  129. package/src/tree/paren.ts +132 -0
  130. package/src/tree/query-condition.ts +47 -0
  131. package/src/tree/quoted.ts +119 -0
  132. package/src/tree/range.ts +101 -0
  133. package/src/tree/reference.ts +1099 -0
  134. package/src/tree/rest.ts +55 -0
  135. package/src/tree/rules-raw.ts +52 -0
  136. package/src/tree/rules.ts +2896 -0
  137. package/src/tree/ruleset.ts +1217 -0
  138. package/src/tree/selector-attr.ts +172 -0
  139. package/src/tree/selector-basic.ts +75 -0
  140. package/src/tree/selector-capture.ts +85 -0
  141. package/src/tree/selector-complex.ts +189 -0
  142. package/src/tree/selector-compound.ts +205 -0
  143. package/src/tree/selector-interpolated.ts +95 -0
  144. package/src/tree/selector-list.ts +245 -0
  145. package/src/tree/selector-pseudo.ts +173 -0
  146. package/src/tree/selector-simple.ts +10 -0
  147. package/src/tree/selector.ts +152 -0
  148. package/src/tree/sequence.ts +463 -0
  149. package/src/tree/tree.ts +130 -0
  150. package/src/tree/url.ts +95 -0
  151. package/src/tree/util/EXTEND_ARCHITECTURE_ANALYSIS.md +215 -0
  152. package/src/tree/util/EXTEND_AUDIT.md +233 -0
  153. package/src/tree/util/EXTEND_BASELINE.md +64 -0
  154. package/src/tree/util/EXTEND_CALL_GRAPH_ANALYSIS.md +244 -0
  155. package/src/tree/util/EXTEND_DOCS.md +24 -0
  156. package/src/tree/util/EXTEND_FINAL_SUMMARY.md +95 -0
  157. package/src/tree/util/EXTEND_FUNCTION_AUDIT.md +1433 -0
  158. package/src/tree/util/EXTEND_OPTIMIZATION_PLAN.md +114 -0
  159. package/src/tree/util/EXTEND_REFACTORING_SUMMARY.md +152 -0
  160. package/src/tree/util/EXTEND_RULES.md +74 -0
  161. package/src/tree/util/EXTEND_UNUSED_FUNCTIONS.md +127 -0
  162. package/src/tree/util/EXTEND_UNUSED_FUNCTIONS_ANALYSIS.md +227 -0
  163. package/src/tree/util/NODE_COPY_REDUCTION_PLAN.md +12 -0
  164. package/src/tree/util/__tests__/EXTEND_TEST_INDEX.md +59 -0
  165. package/src/tree/util/__tests__/OPTIMIZATION-ANALYSIS.md +130 -0
  166. package/src/tree/util/__tests__/WALK_AND_CONSUME_DESIGN.md +138 -0
  167. package/src/tree/util/__tests__/_archive/2026-02-09__OPTIMIZATION-ANALYSIS.md +9 -0
  168. package/src/tree/util/__tests__/_archive/README.md +4 -0
  169. package/src/tree/util/__tests__/bitset.test.ts +142 -0
  170. package/src/tree/util/__tests__/debug-log.ts +50 -0
  171. package/src/tree/util/__tests__/extend-comment-handling.test.ts +187 -0
  172. package/src/tree/util/__tests__/extend-core-unit.test.ts +941 -0
  173. package/src/tree/util/__tests__/extend-pipeline-bench.test.ts +154 -0
  174. package/src/tree/util/__tests__/extend-pipeline-bench.ts +190 -0
  175. package/src/tree/util/__tests__/fast-reject.test.ts +377 -0
  176. package/src/tree/util/__tests__/is-node.test.ts +63 -0
  177. package/src/tree/util/__tests__/list-like.test.ts +63 -0
  178. package/src/tree/util/__tests__/outputwriter.test.ts +523 -0
  179. package/src/tree/util/__tests__/print.test.ts +183 -0
  180. package/src/tree/util/__tests__/process-extends.test.ts +226 -0
  181. package/src/tree/util/__tests__/process-leading-is.test.ts +205 -0
  182. package/src/tree/util/__tests__/recursion-helper.test.ts +184 -0
  183. package/src/tree/util/__tests__/selector-match-unit.test.ts +1427 -0
  184. package/src/tree/util/__tests__/sourcemap.test.ts +117 -0
  185. package/src/tree/util/ampersand-template.ts +9 -0
  186. package/src/tree/util/bitset.ts +194 -0
  187. package/src/tree/util/calculate.ts +11 -0
  188. package/src/tree/util/cast.ts +89 -0
  189. package/src/tree/util/cloning.ts +8 -0
  190. package/src/tree/util/collections.ts +299 -0
  191. package/src/tree/util/compare.ts +90 -0
  192. package/src/tree/util/cursor.ts +171 -0
  193. package/src/tree/util/extend-core.ts +2139 -0
  194. package/src/tree/util/extend-roots.ts +1108 -0
  195. package/src/tree/util/field-helpers.ts +354 -0
  196. package/src/tree/util/is-node.ts +43 -0
  197. package/src/tree/util/list-like.ts +93 -0
  198. package/src/tree/util/mixin-instance-primitives.ts +2020 -0
  199. package/src/tree/util/print.ts +303 -0
  200. package/src/tree/util/process-leading-is.ts +421 -0
  201. package/src/tree/util/recursion-helper.ts +54 -0
  202. package/src/tree/util/regex.ts +2 -0
  203. package/src/tree/util/registry-utils.ts +1953 -0
  204. package/src/tree/util/ruleset-trace.ts +17 -0
  205. package/src/tree/util/scoped-body-eval.ts +320 -0
  206. package/src/tree/util/selector-match-core.ts +2005 -0
  207. package/src/tree/util/selector-utils.ts +757 -0
  208. package/src/tree/util/serialize-helper.ts +535 -0
  209. package/src/tree/util/serialize-types.ts +318 -0
  210. package/src/tree/util/should-operate.ts +78 -0
  211. package/src/tree/util/sourcemap.ts +37 -0
  212. package/src/types/config.ts +247 -0
  213. package/src/types/index.ts +12 -0
  214. package/{lib/types/modes.d.ts → src/types/modes.ts} +2 -1
  215. package/src/types.d.ts +9 -0
  216. package/src/types.ts +68 -0
  217. package/src/use-webpack-resolver.ts +56 -0
  218. package/src/visitor/__tests__/visitor.test.ts +136 -0
  219. package/src/visitor/index.ts +263 -0
  220. package/{lib/visitor/less-visitor.js → src/visitor/less-visitor.ts} +3 -2
  221. package/lib/context.d.ts +0 -352
  222. package/lib/context.d.ts.map +0 -1
  223. package/lib/context.js +0 -636
  224. package/lib/context.js.map +0 -1
  225. package/lib/conversions.d.ts +0 -73
  226. package/lib/conversions.d.ts.map +0 -1
  227. package/lib/conversions.js +0 -253
  228. package/lib/conversions.js.map +0 -1
  229. package/lib/debug-log.d.ts +0 -2
  230. package/lib/debug-log.d.ts.map +0 -1
  231. package/lib/debug-log.js +0 -27
  232. package/lib/debug-log.js.map +0 -1
  233. package/lib/define-function.d.ts +0 -587
  234. package/lib/define-function.d.ts.map +0 -1
  235. package/lib/define-function.js +0 -726
  236. package/lib/define-function.js.map +0 -1
  237. package/lib/deprecation.d.ts +0 -34
  238. package/lib/deprecation.d.ts.map +0 -1
  239. package/lib/deprecation.js +0 -57
  240. package/lib/deprecation.js.map +0 -1
  241. package/lib/jess-error.d.ts +0 -343
  242. package/lib/jess-error.d.ts.map +0 -1
  243. package/lib/jess-error.js +0 -508
  244. package/lib/jess-error.js.map +0 -1
  245. package/lib/logger/deprecation-processing.d.ts +0 -41
  246. package/lib/logger/deprecation-processing.d.ts.map +0 -1
  247. package/lib/logger/deprecation-processing.js +0 -81
  248. package/lib/logger/deprecation-processing.js.map +0 -1
  249. package/lib/logger.d.ts +0 -10
  250. package/lib/logger.d.ts.map +0 -1
  251. package/lib/logger.js +0 -20
  252. package/lib/logger.js.map +0 -1
  253. package/lib/plugin.d.ts +0 -94
  254. package/lib/plugin.d.ts.map +0 -1
  255. package/lib/plugin.js +0 -174
  256. package/lib/plugin.js.map +0 -1
  257. package/lib/tree/ampersand.d.ts +0 -94
  258. package/lib/tree/ampersand.d.ts.map +0 -1
  259. package/lib/tree/ampersand.js +0 -269
  260. package/lib/tree/ampersand.js.map +0 -1
  261. package/lib/tree/any.d.ts +0 -58
  262. package/lib/tree/any.d.ts.map +0 -1
  263. package/lib/tree/any.js +0 -104
  264. package/lib/tree/any.js.map +0 -1
  265. package/lib/tree/at-rule.d.ts +0 -53
  266. package/lib/tree/at-rule.d.ts.map +0 -1
  267. package/lib/tree/at-rule.js +0 -503
  268. package/lib/tree/at-rule.js.map +0 -1
  269. package/lib/tree/block.d.ts +0 -22
  270. package/lib/tree/block.d.ts.map +0 -1
  271. package/lib/tree/block.js +0 -24
  272. package/lib/tree/block.js.map +0 -1
  273. package/lib/tree/bool.d.ts +0 -18
  274. package/lib/tree/bool.d.ts.map +0 -1
  275. package/lib/tree/bool.js +0 -28
  276. package/lib/tree/bool.js.map +0 -1
  277. package/lib/tree/call.d.ts +0 -66
  278. package/lib/tree/call.d.ts.map +0 -1
  279. package/lib/tree/call.js +0 -306
  280. package/lib/tree/call.js.map +0 -1
  281. package/lib/tree/collection.d.ts +0 -30
  282. package/lib/tree/collection.d.ts.map +0 -1
  283. package/lib/tree/collection.js +0 -37
  284. package/lib/tree/collection.js.map +0 -1
  285. package/lib/tree/color.d.ts +0 -101
  286. package/lib/tree/color.d.ts.map +0 -1
  287. package/lib/tree/color.js +0 -513
  288. package/lib/tree/color.js.map +0 -1
  289. package/lib/tree/combinator.d.ts +0 -13
  290. package/lib/tree/combinator.d.ts.map +0 -1
  291. package/lib/tree/combinator.js +0 -12
  292. package/lib/tree/combinator.js.map +0 -1
  293. package/lib/tree/comment.d.ts +0 -20
  294. package/lib/tree/comment.d.ts.map +0 -1
  295. package/lib/tree/comment.js +0 -19
  296. package/lib/tree/comment.js.map +0 -1
  297. package/lib/tree/condition.d.ts +0 -31
  298. package/lib/tree/condition.d.ts.map +0 -1
  299. package/lib/tree/condition.js +0 -103
  300. package/lib/tree/condition.js.map +0 -1
  301. package/lib/tree/control.d.ts +0 -104
  302. package/lib/tree/control.d.ts.map +0 -1
  303. package/lib/tree/control.js +0 -430
  304. package/lib/tree/control.js.map +0 -1
  305. package/lib/tree/declaration-custom.d.ts +0 -18
  306. package/lib/tree/declaration-custom.d.ts.map +0 -1
  307. package/lib/tree/declaration-custom.js +0 -24
  308. package/lib/tree/declaration-custom.js.map +0 -1
  309. package/lib/tree/declaration-var.d.ts +0 -35
  310. package/lib/tree/declaration-var.d.ts.map +0 -1
  311. package/lib/tree/declaration-var.js +0 -63
  312. package/lib/tree/declaration-var.js.map +0 -1
  313. package/lib/tree/declaration.d.ts +0 -78
  314. package/lib/tree/declaration.d.ts.map +0 -1
  315. package/lib/tree/declaration.js +0 -286
  316. package/lib/tree/declaration.js.map +0 -1
  317. package/lib/tree/default-guard.d.ts +0 -15
  318. package/lib/tree/default-guard.d.ts.map +0 -1
  319. package/lib/tree/default-guard.js +0 -19
  320. package/lib/tree/default-guard.js.map +0 -1
  321. package/lib/tree/dimension.d.ts +0 -34
  322. package/lib/tree/dimension.d.ts.map +0 -1
  323. package/lib/tree/dimension.js +0 -294
  324. package/lib/tree/dimension.js.map +0 -1
  325. package/lib/tree/expression.d.ts +0 -25
  326. package/lib/tree/expression.d.ts.map +0 -1
  327. package/lib/tree/expression.js +0 -32
  328. package/lib/tree/expression.js.map +0 -1
  329. package/lib/tree/extend-list.d.ts +0 -23
  330. package/lib/tree/extend-list.d.ts.map +0 -1
  331. package/lib/tree/extend-list.js +0 -23
  332. package/lib/tree/extend-list.js.map +0 -1
  333. package/lib/tree/extend.d.ts +0 -47
  334. package/lib/tree/extend.d.ts.map +0 -1
  335. package/lib/tree/extend.js +0 -296
  336. package/lib/tree/extend.js.map +0 -1
  337. package/lib/tree/function.d.ts +0 -48
  338. package/lib/tree/function.d.ts.map +0 -1
  339. package/lib/tree/function.js +0 -74
  340. package/lib/tree/function.js.map +0 -1
  341. package/lib/tree/import-js.d.ts +0 -35
  342. package/lib/tree/import-js.d.ts.map +0 -1
  343. package/lib/tree/import-js.js +0 -45
  344. package/lib/tree/import-js.js.map +0 -1
  345. package/lib/tree/import-style.d.ts +0 -156
  346. package/lib/tree/import-style.d.ts.map +0 -1
  347. package/lib/tree/import-style.js +0 -566
  348. package/lib/tree/import-style.js.map +0 -1
  349. package/lib/tree/index.d.ts +0 -71
  350. package/lib/tree/index.d.ts.map +0 -1
  351. package/lib/tree/index.js.map +0 -1
  352. package/lib/tree/interpolated-reference.d.ts +0 -24
  353. package/lib/tree/interpolated-reference.d.ts.map +0 -1
  354. package/lib/tree/interpolated-reference.js +0 -37
  355. package/lib/tree/interpolated-reference.js.map +0 -1
  356. package/lib/tree/interpolated.d.ts +0 -62
  357. package/lib/tree/interpolated.d.ts.map +0 -1
  358. package/lib/tree/interpolated.js +0 -204
  359. package/lib/tree/interpolated.js.map +0 -1
  360. package/lib/tree/js-array.d.ts +0 -10
  361. package/lib/tree/js-array.d.ts.map +0 -1
  362. package/lib/tree/js-array.js +0 -10
  363. package/lib/tree/js-array.js.map +0 -1
  364. package/lib/tree/js-expr.d.ts +0 -23
  365. package/lib/tree/js-expr.d.ts.map +0 -1
  366. package/lib/tree/js-expr.js +0 -28
  367. package/lib/tree/js-expr.js.map +0 -1
  368. package/lib/tree/js-function.d.ts +0 -20
  369. package/lib/tree/js-function.d.ts.map +0 -1
  370. package/lib/tree/js-function.js +0 -16
  371. package/lib/tree/js-function.js.map +0 -1
  372. package/lib/tree/js-object.d.ts +0 -10
  373. package/lib/tree/js-object.d.ts.map +0 -1
  374. package/lib/tree/js-object.js +0 -10
  375. package/lib/tree/js-object.js.map +0 -1
  376. package/lib/tree/list.d.ts +0 -38
  377. package/lib/tree/list.d.ts.map +0 -1
  378. package/lib/tree/list.js +0 -83
  379. package/lib/tree/list.js.map +0 -1
  380. package/lib/tree/log.d.ts +0 -29
  381. package/lib/tree/log.d.ts.map +0 -1
  382. package/lib/tree/log.js +0 -56
  383. package/lib/tree/log.js.map +0 -1
  384. package/lib/tree/mixin.d.ts +0 -87
  385. package/lib/tree/mixin.d.ts.map +0 -1
  386. package/lib/tree/mixin.js +0 -112
  387. package/lib/tree/mixin.js.map +0 -1
  388. package/lib/tree/negative.d.ts +0 -17
  389. package/lib/tree/negative.d.ts.map +0 -1
  390. package/lib/tree/negative.js +0 -22
  391. package/lib/tree/negative.js.map +0 -1
  392. package/lib/tree/nil.d.ts +0 -30
  393. package/lib/tree/nil.d.ts.map +0 -1
  394. package/lib/tree/nil.js +0 -35
  395. package/lib/tree/nil.js.map +0 -1
  396. package/lib/tree/node-base.d.ts +0 -361
  397. package/lib/tree/node-base.d.ts.map +0 -1
  398. package/lib/tree/node-base.js +0 -930
  399. package/lib/tree/node-base.js.map +0 -1
  400. package/lib/tree/node.d.ts +0 -10
  401. package/lib/tree/node.d.ts.map +0 -1
  402. package/lib/tree/node.js +0 -45
  403. package/lib/tree/node.js.map +0 -1
  404. package/lib/tree/number.d.ts +0 -21
  405. package/lib/tree/number.d.ts.map +0 -1
  406. package/lib/tree/number.js +0 -27
  407. package/lib/tree/number.js.map +0 -1
  408. package/lib/tree/operation.d.ts +0 -26
  409. package/lib/tree/operation.d.ts.map +0 -1
  410. package/lib/tree/operation.js +0 -103
  411. package/lib/tree/operation.js.map +0 -1
  412. package/lib/tree/paren.d.ts +0 -19
  413. package/lib/tree/paren.d.ts.map +0 -1
  414. package/lib/tree/paren.js +0 -92
  415. package/lib/tree/paren.js.map +0 -1
  416. package/lib/tree/query-condition.d.ts +0 -17
  417. package/lib/tree/query-condition.d.ts.map +0 -1
  418. package/lib/tree/query-condition.js +0 -39
  419. package/lib/tree/query-condition.js.map +0 -1
  420. package/lib/tree/quoted.d.ts +0 -28
  421. package/lib/tree/quoted.d.ts.map +0 -1
  422. package/lib/tree/quoted.js +0 -75
  423. package/lib/tree/quoted.js.map +0 -1
  424. package/lib/tree/range.d.ts +0 -33
  425. package/lib/tree/range.d.ts.map +0 -1
  426. package/lib/tree/range.js +0 -47
  427. package/lib/tree/range.js.map +0 -1
  428. package/lib/tree/reference.d.ts +0 -76
  429. package/lib/tree/reference.d.ts.map +0 -1
  430. package/lib/tree/reference.js +0 -521
  431. package/lib/tree/reference.js.map +0 -1
  432. package/lib/tree/rest.d.ts +0 -15
  433. package/lib/tree/rest.d.ts.map +0 -1
  434. package/lib/tree/rest.js +0 -32
  435. package/lib/tree/rest.js.map +0 -1
  436. package/lib/tree/rules-raw.d.ts +0 -17
  437. package/lib/tree/rules-raw.d.ts.map +0 -1
  438. package/lib/tree/rules-raw.js +0 -37
  439. package/lib/tree/rules-raw.js.map +0 -1
  440. package/lib/tree/rules.d.ts +0 -262
  441. package/lib/tree/rules.d.ts.map +0 -1
  442. package/lib/tree/rules.js +0 -2359
  443. package/lib/tree/rules.js.map +0 -1
  444. package/lib/tree/ruleset.d.ts +0 -92
  445. package/lib/tree/ruleset.d.ts.map +0 -1
  446. package/lib/tree/ruleset.js +0 -528
  447. package/lib/tree/ruleset.js.map +0 -1
  448. package/lib/tree/selector-attr.d.ts +0 -31
  449. package/lib/tree/selector-attr.d.ts.map +0 -1
  450. package/lib/tree/selector-attr.js +0 -99
  451. package/lib/tree/selector-attr.js.map +0 -1
  452. package/lib/tree/selector-basic.d.ts +0 -24
  453. package/lib/tree/selector-basic.d.ts.map +0 -1
  454. package/lib/tree/selector-basic.js +0 -38
  455. package/lib/tree/selector-basic.js.map +0 -1
  456. package/lib/tree/selector-capture.d.ts +0 -23
  457. package/lib/tree/selector-capture.d.ts.map +0 -1
  458. package/lib/tree/selector-capture.js +0 -34
  459. package/lib/tree/selector-capture.js.map +0 -1
  460. package/lib/tree/selector-complex.d.ts +0 -40
  461. package/lib/tree/selector-complex.d.ts.map +0 -1
  462. package/lib/tree/selector-complex.js +0 -143
  463. package/lib/tree/selector-complex.js.map +0 -1
  464. package/lib/tree/selector-compound.d.ts +0 -16
  465. package/lib/tree/selector-compound.d.ts.map +0 -1
  466. package/lib/tree/selector-compound.js +0 -114
  467. package/lib/tree/selector-compound.js.map +0 -1
  468. package/lib/tree/selector-interpolated.d.ts +0 -23
  469. package/lib/tree/selector-interpolated.d.ts.map +0 -1
  470. package/lib/tree/selector-interpolated.js +0 -27
  471. package/lib/tree/selector-interpolated.js.map +0 -1
  472. package/lib/tree/selector-list.d.ts +0 -17
  473. package/lib/tree/selector-list.d.ts.map +0 -1
  474. package/lib/tree/selector-list.js +0 -174
  475. package/lib/tree/selector-list.js.map +0 -1
  476. package/lib/tree/selector-pseudo.d.ts +0 -42
  477. package/lib/tree/selector-pseudo.d.ts.map +0 -1
  478. package/lib/tree/selector-pseudo.js +0 -204
  479. package/lib/tree/selector-pseudo.js.map +0 -1
  480. package/lib/tree/selector-simple.d.ts +0 -5
  481. package/lib/tree/selector-simple.d.ts.map +0 -1
  482. package/lib/tree/selector-simple.js +0 -6
  483. package/lib/tree/selector-simple.js.map +0 -1
  484. package/lib/tree/selector.d.ts +0 -43
  485. package/lib/tree/selector.d.ts.map +0 -1
  486. package/lib/tree/selector.js +0 -56
  487. package/lib/tree/selector.js.map +0 -1
  488. package/lib/tree/sequence.d.ts +0 -43
  489. package/lib/tree/sequence.d.ts.map +0 -1
  490. package/lib/tree/sequence.js +0 -151
  491. package/lib/tree/sequence.js.map +0 -1
  492. package/lib/tree/tree.d.ts +0 -87
  493. package/lib/tree/tree.d.ts.map +0 -1
  494. package/lib/tree/tree.js +0 -2
  495. package/lib/tree/tree.js.map +0 -1
  496. package/lib/tree/url.d.ts +0 -18
  497. package/lib/tree/url.d.ts.map +0 -1
  498. package/lib/tree/url.js +0 -35
  499. package/lib/tree/url.js.map +0 -1
  500. package/lib/tree/util/__tests__/debug-log.d.ts +0 -1
  501. package/lib/tree/util/__tests__/debug-log.d.ts.map +0 -1
  502. package/lib/tree/util/__tests__/debug-log.js +0 -36
  503. package/lib/tree/util/__tests__/debug-log.js.map +0 -1
  504. package/lib/tree/util/calculate.d.ts +0 -3
  505. package/lib/tree/util/calculate.d.ts.map +0 -1
  506. package/lib/tree/util/calculate.js +0 -10
  507. package/lib/tree/util/calculate.js.map +0 -1
  508. package/lib/tree/util/cast.d.ts +0 -10
  509. package/lib/tree/util/cast.d.ts.map +0 -1
  510. package/lib/tree/util/cast.js +0 -87
  511. package/lib/tree/util/cast.js.map +0 -1
  512. package/lib/tree/util/cloning.d.ts +0 -4
  513. package/lib/tree/util/cloning.d.ts.map +0 -1
  514. package/lib/tree/util/cloning.js +0 -8
  515. package/lib/tree/util/cloning.js.map +0 -1
  516. package/lib/tree/util/collections.d.ts +0 -57
  517. package/lib/tree/util/collections.d.ts.map +0 -1
  518. package/lib/tree/util/collections.js +0 -136
  519. package/lib/tree/util/collections.js.map +0 -1
  520. package/lib/tree/util/compare.d.ts +0 -11
  521. package/lib/tree/util/compare.d.ts.map +0 -1
  522. package/lib/tree/util/compare.js +0 -89
  523. package/lib/tree/util/compare.js.map +0 -1
  524. package/lib/tree/util/extend-helpers.d.ts +0 -2
  525. package/lib/tree/util/extend-helpers.d.ts.map +0 -1
  526. package/lib/tree/util/extend-helpers.js +0 -2
  527. package/lib/tree/util/extend-helpers.js.map +0 -1
  528. package/lib/tree/util/extend-roots.d.ts +0 -37
  529. package/lib/tree/util/extend-roots.d.ts.map +0 -1
  530. package/lib/tree/util/extend-roots.js +0 -700
  531. package/lib/tree/util/extend-roots.js.map +0 -1
  532. package/lib/tree/util/extend-roots.old.d.ts +0 -132
  533. package/lib/tree/util/extend-roots.old.d.ts.map +0 -1
  534. package/lib/tree/util/extend-roots.old.js +0 -2272
  535. package/lib/tree/util/extend-roots.old.js.map +0 -1
  536. package/lib/tree/util/extend-trace-debug.d.ts +0 -13
  537. package/lib/tree/util/extend-trace-debug.d.ts.map +0 -1
  538. package/lib/tree/util/extend-trace-debug.js +0 -34
  539. package/lib/tree/util/extend-trace-debug.js.map +0 -1
  540. package/lib/tree/util/extend-walk.d.ts +0 -53
  541. package/lib/tree/util/extend-walk.d.ts.map +0 -1
  542. package/lib/tree/util/extend-walk.js +0 -881
  543. package/lib/tree/util/extend-walk.js.map +0 -1
  544. package/lib/tree/util/extend.d.ts +0 -218
  545. package/lib/tree/util/extend.d.ts.map +0 -1
  546. package/lib/tree/util/extend.js +0 -3182
  547. package/lib/tree/util/extend.js.map +0 -1
  548. package/lib/tree/util/find-extendable-locations.d.ts +0 -2
  549. package/lib/tree/util/find-extendable-locations.d.ts.map +0 -1
  550. package/lib/tree/util/find-extendable-locations.js +0 -2
  551. package/lib/tree/util/find-extendable-locations.js.map +0 -1
  552. package/lib/tree/util/format.d.ts +0 -20
  553. package/lib/tree/util/format.d.ts.map +0 -1
  554. package/lib/tree/util/format.js +0 -67
  555. package/lib/tree/util/format.js.map +0 -1
  556. package/lib/tree/util/is-node.d.ts +0 -13
  557. package/lib/tree/util/is-node.d.ts.map +0 -1
  558. package/lib/tree/util/is-node.js +0 -43
  559. package/lib/tree/util/is-node.js.map +0 -1
  560. package/lib/tree/util/print.d.ts +0 -80
  561. package/lib/tree/util/print.d.ts.map +0 -1
  562. package/lib/tree/util/print.js +0 -205
  563. package/lib/tree/util/print.js.map +0 -1
  564. package/lib/tree/util/process-leading-is.d.ts +0 -25
  565. package/lib/tree/util/process-leading-is.d.ts.map +0 -1
  566. package/lib/tree/util/process-leading-is.js +0 -364
  567. package/lib/tree/util/process-leading-is.js.map +0 -1
  568. package/lib/tree/util/recursion-helper.d.ts +0 -15
  569. package/lib/tree/util/recursion-helper.d.ts.map +0 -1
  570. package/lib/tree/util/recursion-helper.js +0 -43
  571. package/lib/tree/util/recursion-helper.js.map +0 -1
  572. package/lib/tree/util/regex.d.ts +0 -4
  573. package/lib/tree/util/regex.d.ts.map +0 -1
  574. package/lib/tree/util/regex.js +0 -4
  575. package/lib/tree/util/regex.js.map +0 -1
  576. package/lib/tree/util/registry-utils.d.ts +0 -192
  577. package/lib/tree/util/registry-utils.d.ts.map +0 -1
  578. package/lib/tree/util/registry-utils.js +0 -1214
  579. package/lib/tree/util/registry-utils.js.map +0 -1
  580. package/lib/tree/util/ruleset-trace.d.ts +0 -4
  581. package/lib/tree/util/ruleset-trace.d.ts.map +0 -1
  582. package/lib/tree/util/ruleset-trace.js +0 -14
  583. package/lib/tree/util/ruleset-trace.js.map +0 -1
  584. package/lib/tree/util/selector-compare.d.ts +0 -2
  585. package/lib/tree/util/selector-compare.d.ts.map +0 -1
  586. package/lib/tree/util/selector-compare.js +0 -2
  587. package/lib/tree/util/selector-compare.js.map +0 -1
  588. package/lib/tree/util/selector-match-core.d.ts +0 -184
  589. package/lib/tree/util/selector-match-core.d.ts.map +0 -1
  590. package/lib/tree/util/selector-match-core.js +0 -1603
  591. package/lib/tree/util/selector-match-core.js.map +0 -1
  592. package/lib/tree/util/selector-utils.d.ts +0 -30
  593. package/lib/tree/util/selector-utils.d.ts.map +0 -1
  594. package/lib/tree/util/selector-utils.js +0 -100
  595. package/lib/tree/util/selector-utils.js.map +0 -1
  596. package/lib/tree/util/serialize-helper.d.ts +0 -13
  597. package/lib/tree/util/serialize-helper.d.ts.map +0 -1
  598. package/lib/tree/util/serialize-helper.js +0 -387
  599. package/lib/tree/util/serialize-helper.js.map +0 -1
  600. package/lib/tree/util/serialize-types.d.ts +0 -9
  601. package/lib/tree/util/serialize-types.d.ts.map +0 -1
  602. package/lib/tree/util/serialize-types.js +0 -216
  603. package/lib/tree/util/serialize-types.js.map +0 -1
  604. package/lib/tree/util/should-operate.d.ts +0 -23
  605. package/lib/tree/util/should-operate.d.ts.map +0 -1
  606. package/lib/tree/util/should-operate.js +0 -46
  607. package/lib/tree/util/should-operate.js.map +0 -1
  608. package/lib/tree/util/sourcemap.d.ts +0 -7
  609. package/lib/tree/util/sourcemap.d.ts.map +0 -1
  610. package/lib/tree/util/sourcemap.js +0 -25
  611. package/lib/tree/util/sourcemap.js.map +0 -1
  612. package/lib/types/config.d.ts +0 -205
  613. package/lib/types/config.d.ts.map +0 -1
  614. package/lib/types/config.js +0 -2
  615. package/lib/types/config.js.map +0 -1
  616. package/lib/types/index.d.ts +0 -15
  617. package/lib/types/index.d.ts.map +0 -1
  618. package/lib/types/index.js +0 -3
  619. package/lib/types/index.js.map +0 -1
  620. package/lib/types/modes.d.ts.map +0 -1
  621. package/lib/types/modes.js +0 -2
  622. package/lib/types/modes.js.map +0 -1
  623. package/lib/types.d.ts +0 -61
  624. package/lib/types.d.ts.map +0 -1
  625. package/lib/types.js +0 -2
  626. package/lib/types.js.map +0 -1
  627. package/lib/use-webpack-resolver.d.ts +0 -9
  628. package/lib/use-webpack-resolver.d.ts.map +0 -1
  629. package/lib/use-webpack-resolver.js +0 -41
  630. package/lib/use-webpack-resolver.js.map +0 -1
  631. package/lib/visitor/index.d.ts +0 -136
  632. package/lib/visitor/index.d.ts.map +0 -1
  633. package/lib/visitor/index.js +0 -135
  634. package/lib/visitor/index.js.map +0 -1
  635. package/lib/visitor/less-visitor.d.ts +0 -7
  636. package/lib/visitor/less-visitor.d.ts.map +0 -1
  637. package/lib/visitor/less-visitor.js.map +0 -1
package/src/context.ts ADDED
@@ -0,0 +1,896 @@
1
+ import type {
2
+ AtRule,
3
+ Ruleset,
4
+ Rules,
5
+ ImportOptions,
6
+ Node,
7
+ Any,
8
+ Selector
9
+ } from './tree/index.js';
10
+ import { ExtendRootRegistry } from './tree/util/extend-roots.js';
11
+ import { type Operator } from './tree/util/calculate.js';
12
+ import type { RenderKey } from './tree/node-base.js';
13
+ import type { PluginInterface } from './plugin.js';
14
+ import { EqualityMode, MathMode, UnitMode } from './types/modes.js';
15
+ import * as path from 'node:path';
16
+ import { isNode } from './tree/util/is-node.js';
17
+ import { N } from './tree/node-type.js';
18
+ import { shouldOperateWithMathFrames } from './tree/util/should-operate.js';
19
+ import { type ErrorDiagnostic, type WarningDiagnostic, JessError } from './jess-error.js';
20
+ import type { Call } from './tree/call.js';
21
+ import { CallMap } from './tree/util/recursion-helper.js';
22
+ import { createRequire } from 'node:module';
23
+ import { BitSetLibrary } from './tree/util/bitset.js';
24
+ import type { EvalDependency } from './tree/util/field-helpers.js';
25
+
26
+ export interface ContextOptions {
27
+ /** Hash classes for module output */
28
+ module?: boolean;
29
+ /**
30
+ * From docs:
31
+ * "Changes compilation mode so dynamic content
32
+ * is output as CSS variables, and changes
33
+ * the runtime module to generate CSS patches."
34
+ *
35
+ * @todo - Change this behavior to "live expressions"
36
+ * i.e. change compilation to always be static, but
37
+ * generate a separate module for calculated CSS variables.
38
+ */
39
+ dynamic?: boolean;
40
+ collapseNesting?: boolean;
41
+
42
+ enableJavaScript?: boolean;
43
+ mathMode?: MathMode;
44
+ unitMode?: UnitMode;
45
+ equalityMode?: EqualityMode;
46
+
47
+ /** Directories to search to resolve files */
48
+ searchPaths?: string[];
49
+
50
+ /**
51
+ * Whether to leak variables and mixins into the caller scope,
52
+ * such that they can be referenced / called by subsequent rules.
53
+ *
54
+ * @deprecated - a Less feature
55
+ */
56
+ leakyRules?: boolean;
57
+
58
+ /**
59
+ * Whether to bubble root-only at-rules (like @font-face, @keyframes)
60
+ * to the root level when they're nested inside rulesets.
61
+ *
62
+ * @deprecated - a legacy Less feature; modern CSS allows nesting
63
+ */
64
+ bubbleRootAtRules?: boolean;
65
+
66
+ /**
67
+ * Suppress warnings (similar to Less's suppressWarnings option).
68
+ * When true, warnings are collected but not emitted.
69
+ */
70
+ suppressWarnings?: boolean;
71
+
72
+ /**
73
+ * Break on first error (stop processing after first error).
74
+ * When false, errors are collected and processing continues.
75
+ */
76
+ breakOnError?: boolean;
77
+ }
78
+
79
+ export interface TreeContextOptions extends ContextOptions {
80
+ inlineJavaScript?: boolean;
81
+
82
+ /**
83
+ * For instances where a new tree needs to inherit from scope
84
+ * (like Less / SCSS `@import` rule)
85
+ *
86
+ * @todo - remove?
87
+ */
88
+ parentScope?: Rules;
89
+ scope?: Rules;
90
+
91
+ isModule?: boolean;
92
+
93
+ file?: {
94
+ /** Filename, e.g. "main.jess" */
95
+ name: string;
96
+
97
+ /** Absolute directory containing the file (no filename) */
98
+ path: string;
99
+
100
+ /** Absolute file path (directory + filename) */
101
+ fullPath: string;
102
+
103
+ /** Full file contents (recommended for code-frames) */
104
+ source?: string;
105
+
106
+ /** Lazy cache of line-start offsets (built on demand) */
107
+ lines?: Uint32Array;
108
+ };
109
+
110
+ [k: string]: any;
111
+ }
112
+
113
+ const idChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
114
+
115
+ /**
116
+ * @todo - Redo:
117
+ * 1. Create a hash of the file path; that way hashes
118
+ * are unique per file, but also repeatable / predictable.
119
+ * 2. Append file (module) hash after class name
120
+ */
121
+ export const generateId = (length = 8) => {
122
+ let str = '';
123
+ let idCharsLength = idChars.length;
124
+ for (let i = 0; i < length; i++) {
125
+ str += idChars[Math.floor(Math.random() * idCharsLength)]!;
126
+ }
127
+ return str;
128
+ };
129
+
130
+ /**
131
+ * Tree context is attached to each node
132
+ * during the parsing phase / AST creation.
133
+ *
134
+ * Each file (and hence, tree) will get a new tree
135
+ * context. For the most part, it is passed around
136
+ * as an object reference.
137
+ *
138
+ * Additionally, it sets options that may be
139
+ * unique to the tree, such as the math mode.
140
+ */
141
+ export class TreeContext implements TreeContextOptions {
142
+ opts: Record<string, any>;
143
+ // changed to `rulesVisiblity` set during parsing
144
+ leakyRules: boolean | undefined;
145
+ bubbleRootAtRules: boolean | undefined;
146
+ mathMode: MathMode | undefined;
147
+ unitMode: UnitMode | undefined;
148
+ equalityMode: EqualityMode | undefined;
149
+
150
+ /** @todo - Change how extend works based on this value */
151
+ isModule: boolean | undefined;
152
+
153
+ file?: TreeContextOptions['file'];
154
+ /**
155
+ * The plugin that created this tree. It will have first dibs
156
+ * to resolve any imports.
157
+ */
158
+ plugin?: PluginInterface;
159
+
160
+ constructor(opts: TreeContextOptions = {}) {
161
+ /**
162
+ * Known options are attached to the instance.
163
+ * Unknown options are assigned to `opts`
164
+ */
165
+ let {
166
+ mathMode,
167
+ unitMode,
168
+ equalityMode,
169
+ isModule,
170
+ file,
171
+ plugin,
172
+ leakyRules,
173
+ bubbleRootAtRules,
174
+ ...rest
175
+ } = opts;
176
+ this.mathMode = mathMode;
177
+ this.unitMode = unitMode;
178
+ this.equalityMode = equalityMode;
179
+ this.isModule = isModule;
180
+ this.file = file;
181
+ this.plugin = plugin;
182
+ this.leakyRules = leakyRules;
183
+ this.bubbleRootAtRules = bubbleRootAtRules;
184
+ // this.scope = scope ?? new Scope(parentScope)
185
+ this.opts = rest;
186
+ }
187
+ }
188
+
189
+ /**
190
+ * .a.b.c
191
+ * simple = 0b1
192
+ * compound = 0b10
193
+ * complex = 0b100
194
+ * a = 0b1000
195
+ * b = 0b10000
196
+ * c = 0b100000
197
+ *
198
+ * .a.b.c.c = 0b111010
199
+ */
200
+
201
+ /**
202
+ * This is the context object used for evaluation.
203
+ *
204
+ * @note
205
+ * Most of context represents "state" while evaluating.
206
+ * There should only ever be one Context singleton per parse & evaluation.
207
+ */
208
+ export class Context {
209
+ readonly plugins: PluginInterface[];
210
+ readonly opts: ContextOptions;
211
+
212
+ treeContext!: TreeContext;
213
+
214
+ /**
215
+ * Collected errors during safeParse/safeRender.
216
+ * Only populated when using safe methods.
217
+ */
218
+ errors: ErrorDiagnostic[] = [];
219
+
220
+ /**
221
+ * Collected warnings during safeParse/safeRender.
222
+ * Only populated when using safe methods.
223
+ */
224
+ warnings: WarningDiagnostic[] = [];
225
+
226
+ /**
227
+ * A feature ported from Less - we suppress any `@charset`
228
+ * after the first one.
229
+ */
230
+ currentCharset?: Any;
231
+ /** Track whether charset has been emitted during toString to avoid duplicates */
232
+ charsetEmitted?: boolean;
233
+
234
+ /** @import rules must be at the top of CSS output */
235
+ topImports?: Node[];
236
+
237
+ /**
238
+ * This is set when entering rulesets so that child nodes
239
+ * can use this to lookup values. When evaluating inside a mixin/function,
240
+ * this also enables call-time variable resolution ($~variable).
241
+ */
242
+ rulesContext!: Rules;
243
+ /**
244
+ * Internal transient lookup-scope override.
245
+ *
246
+ * Used by direct mixin/function invocation so canonical bodies can evaluate
247
+ * against a prepared outer scope without changing the public node API.
248
+ */
249
+ lookupScope?: Rules;
250
+ /** Entire context root (ultimate root) */
251
+ root!: Rules;
252
+ /** Set so that we can do ruleset selector lookup for extend */
253
+ treeRoot!: Rules;
254
+ allRoots: Rules[] = [];
255
+
256
+ /** The call that is currently being evaluated */
257
+ caller?: Call;
258
+
259
+ /**
260
+ * Current render-key selection for parent/edge-sensitive traversal.
261
+ *
262
+ * Canonical traversal falls back when no alternate edge exists.
263
+ */
264
+ renderKey?: RenderKey;
265
+
266
+ /** Extend roots registry for managing extend scoping */
267
+ extendRoots!: ExtendRootRegistry;
268
+
269
+ /**
270
+ * Depth-first document order of each Ruleset (assigned once per root before eval).
271
+ * Used so processExtends can apply extends in true source order.
272
+ *
273
+ * @todo - Probably remove once I fix extends
274
+ */
275
+ documentOrderByRuleset?: WeakMap<Ruleset, number>;
276
+
277
+ /**
278
+ * Registered extends with their extend root context
279
+ * Format: [target, selectorWithExtend, partial, extendRoot, extendNode, documentOrder?, fromReferenceScope?, namespace?]
280
+ *
281
+ * @todo - Probably remove once I fix extends
282
+ */
283
+ extends: Array<[target: Selector, selectorWithExtend: Selector, partial: boolean, extendRoot: Rules, extendNode: Node, documentOrder?: number, fromReferenceScope?: boolean, namespace?: string]> = [];
284
+
285
+ /**
286
+ * When doing any kind of lookup, the current node and resolved
287
+ * nodes in the search chain are added to prevent recursion errors.
288
+ *
289
+ * Search-scope identity is canonical when available (`sourceNode ?? node`)
290
+ * so derived wrappers do not bypass recursion guards.
291
+ * Also used to track mixins currently being evaluated to prevent infinite recursion.
292
+ */
293
+ private _searchScope: Set<Node> | undefined;
294
+ get searchScope() {
295
+ return (this._searchScope ??= new Set());
296
+ }
297
+
298
+ getSearchScopeIdentity(node: Node): Node {
299
+ return node.sourceNode ?? node;
300
+ }
301
+
302
+ hasInSearchScope(node: Node): boolean {
303
+ return this.searchScope.has(this.getSearchScopeIdentity(node));
304
+ }
305
+
306
+ addToSearchScope(node: Node): void {
307
+ this.searchScope.add(this.getSearchScopeIdentity(node));
308
+ }
309
+
310
+ deleteFromSearchScope(node: Node): void {
311
+ this.searchScope.delete(this.getSearchScopeIdentity(node));
312
+ }
313
+
314
+ /**
315
+ * The file (eval) context should have the same ID at compile-time
316
+ * as run-time, so this ID will be set in `toModule()` output
317
+ *
318
+ * @todo - Make the id a hash of the (project-relative) path + contents
319
+ */
320
+ id = generateId();
321
+ ruleCounter = 0;
322
+ renderCounter = 0;
323
+
324
+ /** Rules depth, used to figure out source order */
325
+ depth = -1;
326
+
327
+ /** Selector valueOf() strings to bitset positions */
328
+ selectorBits = new BitSetLibrary<string>();
329
+
330
+ private _classMap: Map<string, string> | undefined;
331
+ get classMap() {
332
+ return (this._classMap ??= new Map());
333
+ }
334
+
335
+ /** Frames for nested rulesets, used for selector evaluation */
336
+ rulesetFrames: Ruleset[] = [];
337
+ /**
338
+ * When mixin eval clears `rulesetFrames`, this preserves the caller's
339
+ * last ruleset frame so at-rule hoisting can still pick up the caller's
340
+ * selector for the wrapper Ruleset.
341
+ */
342
+ callerRulesetFrame: Ruleset | undefined;
343
+ /** Unified frames array for flat rendering when collapseNesting is true */
344
+ frames: (Ruleset | AtRule)[] = [];
345
+
346
+ /**
347
+ * We push a boolean to this array when entering a calc() call
348
+ * and pop it when leaving. This helps us determine if operations
349
+ * should be performed or not.
350
+ *
351
+ * @todo - can't this just be a number?
352
+ */
353
+ calcFrames = 0;
354
+
355
+ private _callMap: CallMap | undefined;
356
+ get callMap() {
357
+ return (this._callMap ??= new CallMap());
358
+ }
359
+
360
+ private _callStack: Call[] | undefined;
361
+ get callStack() {
362
+ return (this._callStack ??= []);
363
+ }
364
+
365
+ /**
366
+ * Stack to track reference call chain for clearing matched keys at outermost level
367
+ */
368
+ private _referenceStack: number = 0;
369
+ get referenceStack() {
370
+ return this._referenceStack;
371
+ }
372
+
373
+ /**
374
+ * Import-evaluation scope stack.
375
+ *
376
+ * This intentionally models lexical import scope instead of global counters:
377
+ * - each import branch pushes its semantics on entry
378
+ * - each branch pops in `finally`
379
+ * - readers ask semantic questions (`inReferenceImportScope`) instead of
380
+ * inspecting mutable depth values.
381
+ *
382
+ * Why this exists:
383
+ * some behaviors depend on "how we got here" (call-path scope), not only
384
+ * on the current node's own options. Example: suppressing top-level @import
385
+ * hoists while traversing a reference-only branch.
386
+ */
387
+ private _importScopeStack: Array<{ reference: boolean; multiple: boolean }> = [];
388
+ get importScope() {
389
+ return this._importScopeStack;
390
+ }
391
+
392
+ get inReferenceImportScope() {
393
+ return this._importScopeStack.some(scope => scope.reference);
394
+ }
395
+
396
+ get inMultipleImportScope() {
397
+ return this._importScopeStack.some(scope => scope.multiple);
398
+ }
399
+
400
+ pushImportScope(scope: { reference?: boolean; multiple?: boolean }) {
401
+ this._importScopeStack.push({
402
+ reference: scope.reference === true,
403
+ multiple: scope.multiple === true
404
+ });
405
+ }
406
+
407
+ popImportScope() {
408
+ if (this._importScopeStack.length > 0) {
409
+ this._importScopeStack.pop();
410
+ }
411
+ }
412
+
413
+ pushReference() {
414
+ this._referenceStack++;
415
+ }
416
+
417
+ /**
418
+ * Stack to track when a value comes from an important declaration
419
+ * Used to propagate !important flag to containing declarations
420
+ */
421
+ private _importantSourceStack: number = 0;
422
+ get hasImportantSource() {
423
+ return this._importantSourceStack > 0;
424
+ }
425
+
426
+ pushImportantSource() {
427
+ this._importantSourceStack++;
428
+ }
429
+
430
+ popImportantSource() {
431
+ if (this._importantSourceStack > 0) {
432
+ this._importantSourceStack--;
433
+ }
434
+ }
435
+
436
+ popReference() {
437
+ this._referenceStack--;
438
+ }
439
+
440
+ rulesEvalStack: Rules[] = [];
441
+
442
+ /**
443
+ * We push a boolean to this array when entering parens call
444
+ * and pop it when leaving. This helps us determine if operations
445
+ * should be performed or not.
446
+ *
447
+ * Sometimes we "reset" the "in parentheses" state by pushing false,
448
+ * such as within a function call.
449
+ */
450
+ parenFrames: boolean[] = [];
451
+
452
+ /**
453
+ * Keys of @let variables --
454
+ * We need this b/c we need to generate code
455
+ * for over-riding in the exported function.
456
+ *
457
+ * @todo - remove?
458
+ */
459
+ private _exports: Set<string> | undefined;
460
+ get exports(): Set<string> {
461
+ return (this._exports ??= new Set());
462
+ }
463
+
464
+ nextRenderKey(): RenderKey {
465
+ return ++this.renderCounter;
466
+ }
467
+
468
+ /**
469
+ * currently generating a runtime module or not
470
+ * @todo - remove in favor of ToModuleVisitor?
471
+ */
472
+ // isRuntime: boolean
473
+
474
+ /**
475
+ * In a custom declaration's value. All nodes should
476
+ * be preserved as-is and not evaluated, except for
477
+ * $() expressions.
478
+ */
479
+ inCustom: boolean | undefined;
480
+
481
+ /** A flag set when evaluating conditions */
482
+ isDefault: boolean | undefined;
483
+
484
+ readonly dependencyMap = new WeakMap<Node, EvalDependency>();
485
+
486
+ _leakyRules: boolean | undefined;
487
+ get leakyRules() {
488
+ return this._leakyRules ?? this.treeContext?.leakyRules ?? false;
489
+ }
490
+
491
+ _bubbleRootAtRules: boolean | undefined;
492
+ get bubbleRootAtRules() {
493
+ return this._bubbleRootAtRules ?? this.treeContext?.bubbleRootAtRules ?? false;
494
+ }
495
+
496
+ constructor(opts: ContextOptions = {}, plugins?: PluginInterface[]) {
497
+ this.opts = opts;
498
+ this.plugins = plugins ?? [];
499
+ this.extendRoots = new ExtendRootRegistry();
500
+ if (opts.leakyRules !== undefined) {
501
+ this._leakyRules = opts.leakyRules;
502
+ }
503
+ if (opts.bubbleRootAtRules !== undefined) {
504
+ this._bubbleRootAtRules = opts.bubbleRootAtRules;
505
+ }
506
+ }
507
+
508
+ /** Full resolved path -> tree */
509
+ sourceTrees = new Map<string, Rules>();
510
+ evaldTrees = new Map<string, Rules>();
511
+ composeSetValues = new Map<string, Rules>();
512
+
513
+ /**
514
+ * @param importPath - The bare import path e.g. `@import "foo";` in a .less file.
515
+ */
516
+ private async _getPath(importPath: string) {
517
+ const currentTree = this.treeContext;
518
+ const currentDirectory = currentTree?.file?.path ?? process.cwd();
519
+ const { searchPaths = [] } = this.opts;
520
+
521
+ const plugins = this.plugins;
522
+ let finalPath: string | undefined;
523
+ let currentPlugin = this.treeContext?.plugin;
524
+
525
+ /** First, expand imports */
526
+ let paths = currentPlugin?.expandImport?.(importPath, currentDirectory) ?? [importPath];
527
+ if (paths.length === 0) {
528
+ throw new Error(`No paths found for import "${importPath}"`);
529
+ }
530
+
531
+ /** Give current context plugin first dibs to resolve */
532
+ if (currentPlugin?.resolve) {
533
+ const result = await currentPlugin.resolve(paths, currentDirectory, searchPaths);
534
+ if (result) {
535
+ paths = result;
536
+ }
537
+ }
538
+
539
+ /** Try to resolve using resolver plugins */
540
+ for (const plugin of plugins) {
541
+ if (plugin === currentPlugin) {
542
+ continue;
543
+ }
544
+ if (!plugin.resolve) {
545
+ continue;
546
+ }
547
+ const result = await plugin.resolve(paths, currentDirectory, searchPaths);
548
+ if (result) {
549
+ paths = result;
550
+ }
551
+ }
552
+
553
+ /** Now, try to locate the first matching file using locator plugins */
554
+ for (const plugin of plugins) {
555
+ if (!plugin.locate) {
556
+ continue;
557
+ }
558
+ const result = await plugin.locate(paths, currentDirectory);
559
+ if (result) {
560
+ finalPath = result;
561
+ break;
562
+ }
563
+ }
564
+
565
+ if (!finalPath) {
566
+ // Fallback for bare module specifiers (e.g. "@scope/pkg/path").
567
+ const looksBareSpecifier = (p: string) =>
568
+ !path.isAbsolute(p)
569
+ && !p.startsWith('./')
570
+ && !p.startsWith('../')
571
+ && !p.startsWith('/')
572
+ && !/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(p);
573
+ const tryResolveModule = (request: string, basedir: string): string | undefined => {
574
+ try {
575
+ const req = createRequire(path.join(basedir, '__jess_resolve__.js'));
576
+ return req.resolve(request);
577
+ } catch {
578
+ return undefined;
579
+ }
580
+ };
581
+ const moduleBaseDirs = [currentDirectory, ...searchPaths, process.cwd()];
582
+ for (const candidate of paths) {
583
+ if (!looksBareSpecifier(candidate)) {
584
+ continue;
585
+ }
586
+ for (const baseDir of moduleBaseDirs) {
587
+ const base = path.isAbsolute(baseDir) ? baseDir : path.resolve(currentDirectory, baseDir);
588
+ const resolved = tryResolveModule(candidate, base) ?? tryResolveModule(`${candidate}.less`, base);
589
+ if (resolved) {
590
+ finalPath = resolved;
591
+ break;
592
+ }
593
+ }
594
+ if (finalPath) {
595
+ break;
596
+ }
597
+ }
598
+ }
599
+
600
+ if (!finalPath) {
601
+ /** @todo - Add messaging around tried paths */
602
+ throw new Error(`File not found: ${importPath} (from: ${currentDirectory})`);
603
+ }
604
+
605
+ const normalizedFinalPath = finalPath.split(/[?#]/)[0]!;
606
+ const ext = path.extname(normalizedFinalPath);
607
+ const friendlyPath = path.relative(process.cwd(), normalizedFinalPath);
608
+
609
+ if (!ext) {
610
+ throw new Error(`File "${friendlyPath}" not supported`);
611
+ }
612
+
613
+ return {
614
+ triedPaths: paths,
615
+ resolvedPath: normalizedFinalPath,
616
+ friendlyPath
617
+ };
618
+ }
619
+
620
+ /**
621
+ * Find the appropriate plugin for parsing based on type or extension
622
+ */
623
+ private findParserPlugin(type?: string, extension?: string): PluginInterface {
624
+ const plugins = this.plugins;
625
+
626
+ if (type) {
627
+ const plugin = plugins.find(plugin => plugin.name === type);
628
+ if (!plugin) {
629
+ throw new Error(`Plugin "${type}" not found`);
630
+ }
631
+ if (!plugin.parse) {
632
+ throw new Error(`Plugin "${type}" does not support parsing`);
633
+ }
634
+ return plugin;
635
+ }
636
+
637
+ if (extension) {
638
+ const plugin = plugins.find(plugin => plugin.supportedExtensions?.includes(extension) && (plugin.parse || plugin.safeParse));
639
+ if (!plugin) {
640
+ throw new Error(`No plugin found for extension "${extension}"`);
641
+ }
642
+ return plugin;
643
+ }
644
+
645
+ throw new Error('No plugin type or extension specified');
646
+ }
647
+
648
+ async getTree(importPath: string, importOptions: ImportOptions = {}) {
649
+ const { resolvedPath, triedPaths, friendlyPath } = await this._getPath(importPath);
650
+ const { type } = importOptions;
651
+ /**
652
+ * We already have resolved this file and parsed it.
653
+ */
654
+ if (this.sourceTrees.has(resolvedPath)) {
655
+ return {
656
+ node: this.sourceTrees.get(resolvedPath)!,
657
+ triedPaths,
658
+ resolvedPath
659
+ };
660
+ }
661
+
662
+ const plugins = this.plugins;
663
+
664
+ const sourceGetter = plugins.find(plugin => plugin.getSource);
665
+ if (!sourceGetter) {
666
+ /** If we can't actually load files, bail. */
667
+ throw new Error('No source getter found');
668
+ }
669
+
670
+ const ext = path.extname(resolvedPath);
671
+ const plugin = this.findParserPlugin(type, ext);
672
+ let source: string;
673
+ try {
674
+ source = await sourceGetter.getSource!(resolvedPath);
675
+ } catch (error: unknown) {
676
+ throw error;
677
+ }
678
+ const parseResult = plugin.safeParse!(resolvedPath, source, {
679
+ compilerOptions: this.opts
680
+ });
681
+
682
+ // Collect normalized errors and warnings from plugin
683
+ this.errors.push(...parseResult.errors);
684
+ this.warnings.push(...parseResult.warnings);
685
+
686
+ // Check if we have errors and should break
687
+ if (parseResult.errors.length > 0 && this.opts.breakOnError !== false) {
688
+ // Throw the first error as a JessError
689
+ const firstError = parseResult.errors[0]!;
690
+ throw new JessError({
691
+ code: firstError.code,
692
+ phase: firstError.phase,
693
+ severity: 'error',
694
+ ctx: firstError.file ? { file: firstError.file } : undefined,
695
+ filePath: firstError.filePath,
696
+ source: firstError.file?.source,
697
+ line: firstError.line,
698
+ column: firstError.column,
699
+ reason: firstError.reason,
700
+ fix: firstError.fix,
701
+ note: firstError.note,
702
+ errors: firstError.errors,
703
+ lexerErrors: firstError.lexerErrors
704
+ });
705
+ }
706
+
707
+ if (parseResult.tree) {
708
+ // Set context.root so preEval visitors can check if this is the root
709
+ // parseResult.tree should be a Rules node (the root of the parsed tree)
710
+ if (!this.root && isNode(parseResult.tree, N.Rules)) {
711
+ this.root = parseResult.tree;
712
+ }
713
+
714
+ this.sourceTrees.set(resolvedPath, parseResult.tree);
715
+ return {
716
+ node: parseResult.tree,
717
+ triedPaths,
718
+ resolvedPath
719
+ };
720
+ }
721
+
722
+ // No tree and no errors means unsupported file
723
+ const notSupportedError = new Error(`File "${friendlyPath}" not supported`);
724
+ if (this.opts.breakOnError !== false) {
725
+ throw notSupportedError;
726
+ }
727
+ // Add error for unsupported file
728
+ this.errors.push({
729
+ code: 'parse/unsupported-file',
730
+ phase: 'parse',
731
+ message: notSupportedError.message,
732
+ reason: `The file "${friendlyPath}" is not supported by any available plugin.`,
733
+ fix: 'Ensure the file has a supported extension or specify a plugin type.',
734
+ filePath: resolvedPath,
735
+ line: 1,
736
+ column: 1
737
+ });
738
+ return {
739
+ node: null,
740
+ triedPaths,
741
+ resolvedPath
742
+ };
743
+ }
744
+
745
+ /**
746
+ * Public path resolution for import nodes that need source-path lookups
747
+ * without triggering parse/eval.
748
+ */
749
+ async resolveImportPath(importPath: string) {
750
+ return this._getPath(importPath);
751
+ }
752
+
753
+ /**
754
+ * Parse a string content directly using the appropriate plugin
755
+ */
756
+ async parseString(content: string, options: {
757
+ filePath?: string;
758
+ type?: string;
759
+ extension?: string;
760
+ } = {}) {
761
+ const { filePath, type, extension } = options;
762
+ const virtualPath = filePath || `virtual.${extension || 'jess'}`;
763
+ const ext = extension || path.extname(virtualPath);
764
+
765
+ const plugin = this.findParserPlugin(type, ext);
766
+ const tree = await plugin.parse!(virtualPath, content, {
767
+ compilerOptions: this.opts
768
+ });
769
+
770
+ if (!tree) {
771
+ throw new Error('Failed to parse content');
772
+ }
773
+
774
+ return {
775
+ node: tree,
776
+ resolvedPath: virtualPath
777
+ };
778
+ }
779
+
780
+ /**
781
+ *
782
+ * @param importPath
783
+ * @param importOptions
784
+ */
785
+ async getModule(importPath: string, importOptions: ImportOptions = {}) {
786
+ const isFnsImport = importPath === '@jesscss/fns'
787
+ || importPath.startsWith('@jesscss/fns/')
788
+ || importPath === '#less'
789
+ || importPath.startsWith('#less/')
790
+ || importPath === '#sass'
791
+ || importPath.startsWith('#sass/');
792
+ const { enableJavaScript } = this.opts;
793
+ if (enableJavaScript === false && !isFnsImport) {
794
+ throw new Error('JavaScript evaluation is disabled');
795
+ }
796
+ const { resolvedPath, triedPaths, friendlyPath } = await this._getPath(importPath);
797
+ const { type } = importOptions;
798
+
799
+ const plugins = this.plugins;
800
+ const ext = path.extname(resolvedPath);
801
+
802
+ let plugin: PluginInterface | undefined;
803
+
804
+ if (type) {
805
+ plugin = plugins.find(plugin => plugin.name === type);
806
+ if (!plugin) {
807
+ throw new Error(`Plugin "${type}" not found`);
808
+ }
809
+ if (!plugin.import) {
810
+ throw new Error(`Plugin "${type}" can't import modules`);
811
+ }
812
+ }
813
+
814
+ if (!plugin) {
815
+ plugin = plugins.find(plugin => plugin.supportedExtensions?.includes(ext) && plugin.import);
816
+ if (!plugin) {
817
+ if (['.js', '.mjs', '.cjs', '.ts', '.mts', '.cts'].includes(ext)) {
818
+ throw new Error('Feature not supported. Install @jesscss/plugin-js to enable script execution features.');
819
+ }
820
+ throw new Error(`File "${friendlyPath}" not supported`);
821
+ }
822
+ }
823
+
824
+ const module = await plugin.import!(resolvedPath);
825
+ if (!module) {
826
+ throw new Error(`File "${friendlyPath}" not supported`);
827
+ }
828
+
829
+ return {
830
+ module,
831
+ triedPaths,
832
+ resolvedPath
833
+ };
834
+ }
835
+
836
+ // async getRules(
837
+ // filePath: string,
838
+ // nodeOptions: StyleImportOptions,
839
+ // userOptions: Record<string, any> = {},
840
+ // withNode?: StyleImportValue['withNode']
841
+ // ) {
842
+ // let rules = await this.getTree(filePath, userOptions);
843
+ // if (withValues && isNode(withValues.node, 'Rules')) {
844
+ // if (rules.options.readonly) {
845
+ // throw new Error('Cannot set an import\'s "with" values more than once.');
846
+ // }
847
+ // /** @todo - Throw errors for undefined vars */
848
+ // let withRules = withValues.node.clone(true) as Rules;
849
+ // withRules.value.unshift(rules);
850
+ // rules = withRules;
851
+ // if (withValues.type === 'set') {
852
+ // this.sourceTrees.set(filePath, rules);
853
+ // }
854
+ // }
855
+ // return rules;
856
+ // }
857
+
858
+ /**
859
+ * Hash a CSS class name or not depending on the `module` setting
860
+ *
861
+ * @todo - do module files have different contexts, therefore different
862
+ * hash maps?
863
+ */
864
+ hashClass(name: string) {
865
+ /** Remove dot for mapping */
866
+ name = name.slice(1);
867
+ let lookup = this.classMap.get(name);
868
+ if (lookup) {
869
+ return `.${lookup}`;
870
+ }
871
+ let mapVal: string;
872
+ if (this.opts.module) {
873
+ mapVal = `${name}_${this.id}`;
874
+ } else {
875
+ mapVal = name;
876
+ }
877
+ this.classMap.set(name, mapVal);
878
+ return `.${mapVal}`;
879
+ }
880
+
881
+ shouldOperate(op: Operator, left: Node, right: Node) {
882
+ const mathMode = this.treeContext?.mathMode
883
+ ?? this.opts?.mathMode
884
+ ?? 'parens-division';
885
+ return shouldOperateWithMathFrames(
886
+ {
887
+ mathMode,
888
+ parenFrames: this.parenFrames,
889
+ calcFrames: this.calcFrames
890
+ },
891
+ op,
892
+ left,
893
+ right
894
+ );
895
+ }
896
+ }