@tenphi/tasty 0.0.0-snapshot.09c74e2

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 (243) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +539 -0
  3. package/dist/_virtual/_rolldown/runtime.js +8 -0
  4. package/dist/chunks/cacheKey.js +70 -0
  5. package/dist/chunks/cacheKey.js.map +1 -0
  6. package/dist/chunks/definitions.d.ts +37 -0
  7. package/dist/chunks/definitions.js +260 -0
  8. package/dist/chunks/definitions.js.map +1 -0
  9. package/dist/chunks/renderChunk.js +61 -0
  10. package/dist/chunks/renderChunk.js.map +1 -0
  11. package/dist/config.d.ts +280 -0
  12. package/dist/config.js +403 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/core/index.d.ts +33 -0
  15. package/dist/core/index.js +26 -0
  16. package/dist/debug.d.ts +204 -0
  17. package/dist/debug.js +733 -0
  18. package/dist/debug.js.map +1 -0
  19. package/dist/hooks/useGlobalStyles.d.ts +27 -0
  20. package/dist/hooks/useGlobalStyles.js +56 -0
  21. package/dist/hooks/useGlobalStyles.js.map +1 -0
  22. package/dist/hooks/useKeyframes.d.ts +56 -0
  23. package/dist/hooks/useKeyframes.js +54 -0
  24. package/dist/hooks/useKeyframes.js.map +1 -0
  25. package/dist/hooks/useProperty.d.ts +79 -0
  26. package/dist/hooks/useProperty.js +91 -0
  27. package/dist/hooks/useProperty.js.map +1 -0
  28. package/dist/hooks/useRawCSS.d.ts +53 -0
  29. package/dist/hooks/useRawCSS.js +28 -0
  30. package/dist/hooks/useRawCSS.js.map +1 -0
  31. package/dist/hooks/useStyles.d.ts +40 -0
  32. package/dist/hooks/useStyles.js +169 -0
  33. package/dist/hooks/useStyles.js.map +1 -0
  34. package/dist/index.d.ts +48 -0
  35. package/dist/index.js +33 -0
  36. package/dist/injector/index.d.ts +157 -0
  37. package/dist/injector/index.js +154 -0
  38. package/dist/injector/index.js.map +1 -0
  39. package/dist/injector/injector.d.ts +139 -0
  40. package/dist/injector/injector.js +404 -0
  41. package/dist/injector/injector.js.map +1 -0
  42. package/dist/injector/sheet-manager.d.ts +127 -0
  43. package/dist/injector/sheet-manager.js +714 -0
  44. package/dist/injector/sheet-manager.js.map +1 -0
  45. package/dist/injector/types.d.ts +135 -0
  46. package/dist/keyframes/index.js +206 -0
  47. package/dist/keyframes/index.js.map +1 -0
  48. package/dist/parser/classify.js +319 -0
  49. package/dist/parser/classify.js.map +1 -0
  50. package/dist/parser/const.js +33 -0
  51. package/dist/parser/const.js.map +1 -0
  52. package/dist/parser/lru.js +109 -0
  53. package/dist/parser/lru.js.map +1 -0
  54. package/dist/parser/parser.d.ts +25 -0
  55. package/dist/parser/parser.js +116 -0
  56. package/dist/parser/parser.js.map +1 -0
  57. package/dist/parser/tokenizer.js +69 -0
  58. package/dist/parser/tokenizer.js.map +1 -0
  59. package/dist/parser/types.d.ts +51 -0
  60. package/dist/parser/types.js +46 -0
  61. package/dist/parser/types.js.map +1 -0
  62. package/dist/pipeline/conditions.d.ts +134 -0
  63. package/dist/pipeline/conditions.js +406 -0
  64. package/dist/pipeline/conditions.js.map +1 -0
  65. package/dist/pipeline/exclusive.js +231 -0
  66. package/dist/pipeline/exclusive.js.map +1 -0
  67. package/dist/pipeline/index.d.ts +53 -0
  68. package/dist/pipeline/index.js +660 -0
  69. package/dist/pipeline/index.js.map +1 -0
  70. package/dist/pipeline/materialize.js +844 -0
  71. package/dist/pipeline/materialize.js.map +1 -0
  72. package/dist/pipeline/parseStateKey.d.ts +15 -0
  73. package/dist/pipeline/parseStateKey.js +438 -0
  74. package/dist/pipeline/parseStateKey.js.map +1 -0
  75. package/dist/pipeline/simplify.js +516 -0
  76. package/dist/pipeline/simplify.js.map +1 -0
  77. package/dist/pipeline/warnings.js +18 -0
  78. package/dist/pipeline/warnings.js.map +1 -0
  79. package/dist/plugins/okhsl-plugin.d.ts +35 -0
  80. package/dist/plugins/okhsl-plugin.js +371 -0
  81. package/dist/plugins/okhsl-plugin.js.map +1 -0
  82. package/dist/plugins/types.d.ts +69 -0
  83. package/dist/properties/index.js +158 -0
  84. package/dist/properties/index.js.map +1 -0
  85. package/dist/states/index.d.ts +49 -0
  86. package/dist/states/index.js +416 -0
  87. package/dist/states/index.js.map +1 -0
  88. package/dist/static/index.d.ts +5 -0
  89. package/dist/static/index.js +5 -0
  90. package/dist/static/tastyStatic.d.ts +46 -0
  91. package/dist/static/tastyStatic.js +31 -0
  92. package/dist/static/tastyStatic.js.map +1 -0
  93. package/dist/static/types.d.ts +49 -0
  94. package/dist/static/types.js +24 -0
  95. package/dist/static/types.js.map +1 -0
  96. package/dist/styles/align.d.ts +15 -0
  97. package/dist/styles/align.js +14 -0
  98. package/dist/styles/align.js.map +1 -0
  99. package/dist/styles/border.d.ts +25 -0
  100. package/dist/styles/border.js +114 -0
  101. package/dist/styles/border.js.map +1 -0
  102. package/dist/styles/color.d.ts +14 -0
  103. package/dist/styles/color.js +23 -0
  104. package/dist/styles/color.js.map +1 -0
  105. package/dist/styles/createStyle.js +77 -0
  106. package/dist/styles/createStyle.js.map +1 -0
  107. package/dist/styles/dimension.js +97 -0
  108. package/dist/styles/dimension.js.map +1 -0
  109. package/dist/styles/display.d.ts +37 -0
  110. package/dist/styles/display.js +67 -0
  111. package/dist/styles/display.js.map +1 -0
  112. package/dist/styles/fade.d.ts +15 -0
  113. package/dist/styles/fade.js +58 -0
  114. package/dist/styles/fade.js.map +1 -0
  115. package/dist/styles/fill.d.ts +42 -0
  116. package/dist/styles/fill.js +52 -0
  117. package/dist/styles/fill.js.map +1 -0
  118. package/dist/styles/flow.d.ts +16 -0
  119. package/dist/styles/flow.js +12 -0
  120. package/dist/styles/flow.js.map +1 -0
  121. package/dist/styles/gap.d.ts +31 -0
  122. package/dist/styles/gap.js +37 -0
  123. package/dist/styles/gap.js.map +1 -0
  124. package/dist/styles/height.d.ts +17 -0
  125. package/dist/styles/height.js +20 -0
  126. package/dist/styles/height.js.map +1 -0
  127. package/dist/styles/index.d.ts +2 -0
  128. package/dist/styles/index.js +9 -0
  129. package/dist/styles/index.js.map +1 -0
  130. package/dist/styles/inset.d.ts +52 -0
  131. package/dist/styles/inset.js +150 -0
  132. package/dist/styles/inset.js.map +1 -0
  133. package/dist/styles/justify.d.ts +15 -0
  134. package/dist/styles/justify.js +14 -0
  135. package/dist/styles/justify.js.map +1 -0
  136. package/dist/styles/list.d.ts +16 -0
  137. package/dist/styles/list.js +98 -0
  138. package/dist/styles/list.js.map +1 -0
  139. package/dist/styles/margin.d.ts +24 -0
  140. package/dist/styles/margin.js +104 -0
  141. package/dist/styles/margin.js.map +1 -0
  142. package/dist/styles/outline.d.ts +29 -0
  143. package/dist/styles/outline.js +65 -0
  144. package/dist/styles/outline.js.map +1 -0
  145. package/dist/styles/padding.d.ts +24 -0
  146. package/dist/styles/padding.js +104 -0
  147. package/dist/styles/padding.js.map +1 -0
  148. package/dist/styles/predefined.d.ts +73 -0
  149. package/dist/styles/predefined.js +241 -0
  150. package/dist/styles/predefined.js.map +1 -0
  151. package/dist/styles/preset.d.ts +47 -0
  152. package/dist/styles/preset.js +126 -0
  153. package/dist/styles/preset.js.map +1 -0
  154. package/dist/styles/radius.d.ts +14 -0
  155. package/dist/styles/radius.js +51 -0
  156. package/dist/styles/radius.js.map +1 -0
  157. package/dist/styles/scrollbar.d.ts +21 -0
  158. package/dist/styles/scrollbar.js +112 -0
  159. package/dist/styles/scrollbar.js.map +1 -0
  160. package/dist/styles/shadow.d.ts +14 -0
  161. package/dist/styles/shadow.js +24 -0
  162. package/dist/styles/shadow.js.map +1 -0
  163. package/dist/styles/styledScrollbar.d.ts +47 -0
  164. package/dist/styles/styledScrollbar.js +38 -0
  165. package/dist/styles/styledScrollbar.js.map +1 -0
  166. package/dist/styles/transition.d.ts +14 -0
  167. package/dist/styles/transition.js +158 -0
  168. package/dist/styles/transition.js.map +1 -0
  169. package/dist/styles/types.d.ts +498 -0
  170. package/dist/styles/width.d.ts +17 -0
  171. package/dist/styles/width.js +20 -0
  172. package/dist/styles/width.js.map +1 -0
  173. package/dist/tasty.d.ts +982 -0
  174. package/dist/tasty.js +206 -0
  175. package/dist/tasty.js.map +1 -0
  176. package/dist/tokens/typography.d.ts +19 -0
  177. package/dist/tokens/typography.js +237 -0
  178. package/dist/tokens/typography.js.map +1 -0
  179. package/dist/types.d.ts +184 -0
  180. package/dist/utils/cache-wrapper.js +26 -0
  181. package/dist/utils/cache-wrapper.js.map +1 -0
  182. package/dist/utils/case-converter.js +8 -0
  183. package/dist/utils/case-converter.js.map +1 -0
  184. package/dist/utils/colors.d.ts +5 -0
  185. package/dist/utils/colors.js +9 -0
  186. package/dist/utils/colors.js.map +1 -0
  187. package/dist/utils/css-types.d.ts +7 -0
  188. package/dist/utils/dotize.d.ts +26 -0
  189. package/dist/utils/dotize.js +122 -0
  190. package/dist/utils/dotize.js.map +1 -0
  191. package/dist/utils/filter-base-props.d.ts +15 -0
  192. package/dist/utils/filter-base-props.js +45 -0
  193. package/dist/utils/filter-base-props.js.map +1 -0
  194. package/dist/utils/get-display-name.d.ts +7 -0
  195. package/dist/utils/get-display-name.js +10 -0
  196. package/dist/utils/get-display-name.js.map +1 -0
  197. package/dist/utils/hsl-to-rgb.js +38 -0
  198. package/dist/utils/hsl-to-rgb.js.map +1 -0
  199. package/dist/utils/is-dev-env.js +19 -0
  200. package/dist/utils/is-dev-env.js.map +1 -0
  201. package/dist/utils/is-valid-element-type.js +15 -0
  202. package/dist/utils/is-valid-element-type.js.map +1 -0
  203. package/dist/utils/merge-styles.d.ts +7 -0
  204. package/dist/utils/merge-styles.js +146 -0
  205. package/dist/utils/merge-styles.js.map +1 -0
  206. package/dist/utils/mod-attrs.d.ts +8 -0
  207. package/dist/utils/mod-attrs.js +21 -0
  208. package/dist/utils/mod-attrs.js.map +1 -0
  209. package/dist/utils/okhsl-to-rgb.js +296 -0
  210. package/dist/utils/okhsl-to-rgb.js.map +1 -0
  211. package/dist/utils/process-tokens.d.ts +31 -0
  212. package/dist/utils/process-tokens.js +171 -0
  213. package/dist/utils/process-tokens.js.map +1 -0
  214. package/dist/utils/resolve-recipes.d.ts +17 -0
  215. package/dist/utils/resolve-recipes.js +147 -0
  216. package/dist/utils/resolve-recipes.js.map +1 -0
  217. package/dist/utils/string.js +8 -0
  218. package/dist/utils/string.js.map +1 -0
  219. package/dist/utils/styles.d.ts +178 -0
  220. package/dist/utils/styles.js +590 -0
  221. package/dist/utils/styles.js.map +1 -0
  222. package/dist/utils/typography.d.ts +36 -0
  223. package/dist/utils/typography.js +53 -0
  224. package/dist/utils/typography.js.map +1 -0
  225. package/dist/utils/warnings.d.ts +16 -0
  226. package/dist/utils/warnings.js +16 -0
  227. package/dist/utils/warnings.js.map +1 -0
  228. package/dist/zero/babel.d.ts +108 -0
  229. package/dist/zero/babel.js +282 -0
  230. package/dist/zero/babel.js.map +1 -0
  231. package/dist/zero/css-writer.d.ts +45 -0
  232. package/dist/zero/css-writer.js +74 -0
  233. package/dist/zero/css-writer.js.map +1 -0
  234. package/dist/zero/extractor.d.ts +24 -0
  235. package/dist/zero/extractor.js +150 -0
  236. package/dist/zero/extractor.js.map +1 -0
  237. package/dist/zero/index.d.ts +3 -0
  238. package/dist/zero/index.js +4 -0
  239. package/dist/zero/next.d.ts +60 -0
  240. package/dist/zero/next.js +78 -0
  241. package/dist/zero/next.js.map +1 -0
  242. package/package.json +189 -0
  243. package/tasty.config.ts +14 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","names":[],"sources":["../../src/parser/parser.ts"],"sourcesContent":["import { classify } from './classify';\nimport { Lru } from './lru';\nimport { scan } from './tokenizer';\nimport type {\n ParserOptions,\n ProcessedStyle,\n StyleDetails,\n StyleDetailsPart,\n} from './types';\nimport {\n Bucket,\n finalizeGroup,\n finalizePart,\n makeEmptyDetails,\n makeEmptyPart,\n} from './types';\n\nexport class StyleParser {\n private cache: Lru<string, ProcessedStyle>;\n constructor(private opts: ParserOptions = {}) {\n this.cache = new Lru<string, ProcessedStyle>(this.opts.cacheSize ?? 1000);\n }\n\n /* ---------------- Public API ---------------- */\n process(src: string): ProcessedStyle {\n const key = String(src);\n const hit = this.cache.get(key);\n if (hit) return hit;\n\n // strip comments & lower-case once\n const stripped = src\n .replace(/\\/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*\\//g, '')\n .toLowerCase();\n\n const groups: StyleDetails[] = [];\n let currentGroup = makeEmptyDetails();\n let currentPart = makeEmptyPart();\n let parts: StyleDetailsPart[] = [];\n\n const pushToken = (bucket: Bucket, processed: string) => {\n if (!processed) return;\n\n // If the previous token was a url(...) value, merge this token into it so that\n // background layer segments like \"url(img) no-repeat center/cover\" are kept\n // as a single value entry.\n const mergeIntoPrevUrl = () => {\n const lastIdx = currentPart.values.length - 1;\n currentPart.values[lastIdx] += ` ${processed}`;\n const lastAllIdx = currentPart.all.length - 1;\n currentPart.all[lastAllIdx] += ` ${processed}`;\n };\n\n const prevIsUrlValue =\n currentPart.values.length > 0 &&\n currentPart.values[currentPart.values.length - 1].startsWith('url(');\n\n if (prevIsUrlValue) {\n // Extend the existing url(...) value regardless of current bucket.\n mergeIntoPrevUrl();\n // Additionally, for non-value buckets we need to remove their own storage.\n // So early return.\n return;\n }\n\n switch (bucket) {\n case Bucket.Color:\n currentPart.colors.push(processed);\n break;\n case Bucket.Value:\n currentPart.values.push(processed);\n break;\n case Bucket.Mod:\n currentPart.mods.push(processed);\n break;\n }\n currentPart.all.push(processed);\n };\n\n const endPart = () => {\n // Only add non-empty parts\n if (currentPart.all.length > 0) {\n finalizePart(currentPart);\n parts.push(currentPart);\n }\n currentPart = makeEmptyPart();\n };\n\n const endGroup = () => {\n endPart(); // finalize last part\n\n // Ensure at least one part exists (even if empty) for backward compat\n if (parts.length === 0) {\n parts.push(makeEmptyPart());\n finalizePart(parts[0]);\n }\n\n finalizeGroup(currentGroup, parts);\n groups.push(currentGroup);\n\n // Reset for next group\n currentGroup = makeEmptyDetails();\n parts = [];\n currentPart = makeEmptyPart();\n };\n\n scan(stripped, (tok, isComma, isSlash, _prevChar) => {\n if (tok) {\n // Accumulate raw token into currentGroup.input\n if (currentGroup.input) {\n currentGroup.input += ` ${tok}`;\n } else {\n currentGroup.input = tok;\n }\n\n const { bucket, processed } = classify(tok, this.opts, (sub) =>\n this.process(sub),\n );\n pushToken(bucket, processed);\n }\n if (isSlash) endPart();\n if (isComma) endGroup();\n });\n\n // push final group if not already\n if (currentPart.all.length || parts.length || !groups.length) endGroup();\n\n const output = groups.map((g) => g.output).join(', ');\n const result: ProcessedStyle = { output, groups };\n Object.freeze(result);\n this.cache.set(key, result);\n return result;\n }\n\n setFuncs(funcs: Required<ParserOptions>['funcs']): void {\n this.opts.funcs = funcs;\n this.cache.clear();\n }\n\n setUnits(units: Required<ParserOptions>['units']): void {\n this.opts.units = units;\n this.cache.clear();\n }\n\n updateOptions(patch: Partial<ParserOptions>): void {\n Object.assign(this.opts, patch);\n if (patch.cacheSize)\n this.cache = new Lru<string, ProcessedStyle>(patch.cacheSize);\n else this.cache.clear();\n }\n\n /**\n * Clear the parser cache.\n * Call this when external state that affects parsing results has changed\n * (e.g., predefined tokens).\n */\n clearCache(): void {\n this.cache.clear();\n }\n\n /**\n * Get the current units configuration.\n */\n getUnits(): ParserOptions['units'] {\n return this.opts.units;\n }\n}\n\n// Re-export\nexport type { StyleDetails, ProcessedStyle } from './types';\n"],"mappings":";;;;;;AAiBA,IAAa,cAAb,MAAyB;CACvB,AAAQ;CACR,YAAY,AAAQ,OAAsB,EAAE,EAAE;EAA1B;AAClB,OAAK,QAAQ,IAAI,IAA4B,KAAK,KAAK,aAAa,IAAK;;CAI3E,QAAQ,KAA6B;EACnC,MAAM,MAAM,OAAO,IAAI;EACvB,MAAM,MAAM,KAAK,MAAM,IAAI,IAAI;AAC/B,MAAI,IAAK,QAAO;EAGhB,MAAM,WAAW,IACd,QAAQ,qCAAqC,GAAG,CAChD,aAAa;EAEhB,MAAM,SAAyB,EAAE;EACjC,IAAI,eAAe,kBAAkB;EACrC,IAAI,cAAc,eAAe;EACjC,IAAI,QAA4B,EAAE;EAElC,MAAM,aAAa,QAAgB,cAAsB;AACvD,OAAI,CAAC,UAAW;GAKhB,MAAM,yBAAyB;IAC7B,MAAM,UAAU,YAAY,OAAO,SAAS;AAC5C,gBAAY,OAAO,YAAY,IAAI;IACnC,MAAM,aAAa,YAAY,IAAI,SAAS;AAC5C,gBAAY,IAAI,eAAe,IAAI;;AAOrC,OAHE,YAAY,OAAO,SAAS,KAC5B,YAAY,OAAO,YAAY,OAAO,SAAS,GAAG,WAAW,OAAO,EAElD;AAElB,sBAAkB;AAGlB;;AAGF,WAAQ,QAAR;IACE,KAAK,OAAO;AACV,iBAAY,OAAO,KAAK,UAAU;AAClC;IACF,KAAK,OAAO;AACV,iBAAY,OAAO,KAAK,UAAU;AAClC;IACF,KAAK,OAAO;AACV,iBAAY,KAAK,KAAK,UAAU;AAChC;;AAEJ,eAAY,IAAI,KAAK,UAAU;;EAGjC,MAAM,gBAAgB;AAEpB,OAAI,YAAY,IAAI,SAAS,GAAG;AAC9B,iBAAa,YAAY;AACzB,UAAM,KAAK,YAAY;;AAEzB,iBAAc,eAAe;;EAG/B,MAAM,iBAAiB;AACrB,YAAS;AAGT,OAAI,MAAM,WAAW,GAAG;AACtB,UAAM,KAAK,eAAe,CAAC;AAC3B,iBAAa,MAAM,GAAG;;AAGxB,iBAAc,cAAc,MAAM;AAClC,UAAO,KAAK,aAAa;AAGzB,kBAAe,kBAAkB;AACjC,WAAQ,EAAE;AACV,iBAAc,eAAe;;AAG/B,OAAK,WAAW,KAAK,SAAS,SAAS,cAAc;AACnD,OAAI,KAAK;AAEP,QAAI,aAAa,MACf,cAAa,SAAS,IAAI;QAE1B,cAAa,QAAQ;IAGvB,MAAM,EAAE,QAAQ,cAAc,SAAS,KAAK,KAAK,OAAO,QACtD,KAAK,QAAQ,IAAI,CAClB;AACD,cAAU,QAAQ,UAAU;;AAE9B,OAAI,QAAS,UAAS;AACtB,OAAI,QAAS,WAAU;IACvB;AAGF,MAAI,YAAY,IAAI,UAAU,MAAM,UAAU,CAAC,OAAO,OAAQ,WAAU;EAGxE,MAAM,SAAyB;GAAE,QADlB,OAAO,KAAK,MAAM,EAAE,OAAO,CAAC,KAAK,KAAK;GACZ;GAAQ;AACjD,SAAO,OAAO,OAAO;AACrB,OAAK,MAAM,IAAI,KAAK,OAAO;AAC3B,SAAO;;CAGT,SAAS,OAA+C;AACtD,OAAK,KAAK,QAAQ;AAClB,OAAK,MAAM,OAAO;;CAGpB,SAAS,OAA+C;AACtD,OAAK,KAAK,QAAQ;AAClB,OAAK,MAAM,OAAO;;CAGpB,cAAc,OAAqC;AACjD,SAAO,OAAO,KAAK,MAAM,MAAM;AAC/B,MAAI,MAAM,UACR,MAAK,QAAQ,IAAI,IAA4B,MAAM,UAAU;MAC1D,MAAK,MAAM,OAAO;;;;;;;CAQzB,aAAmB;AACjB,OAAK,MAAM,OAAO;;;;;CAMpB,WAAmC;AACjC,SAAO,KAAK,KAAK"}
@@ -0,0 +1,69 @@
1
+ //#region src/parser/tokenizer.ts
2
+ const isWhitespace = (ch) => ch === " " || ch === "\n" || ch === " " || ch === "\r" || ch === "\f";
3
+ function scan(src, cb) {
4
+ let depth = 0;
5
+ let inUrl = false;
6
+ let inQuote = 0;
7
+ let start = 0;
8
+ let i = 0;
9
+ let pendingSlash = false;
10
+ const flush = (isComma, isSlash) => {
11
+ const actualSlash = isSlash || pendingSlash;
12
+ pendingSlash = false;
13
+ if (start < i) {
14
+ const prevChar = start > 0 ? src[start - 1] : null;
15
+ cb(src.slice(start, i), isComma, actualSlash, prevChar);
16
+ } else if (isComma) cb("", true, false, null);
17
+ else if (actualSlash) cb("", false, true, null);
18
+ start = i + 1;
19
+ };
20
+ for (; i < src.length; i++) {
21
+ const ch = src[i];
22
+ if (inQuote) {
23
+ if (ch === inQuote && src[i - 1] !== "\\") inQuote = 0;
24
+ continue;
25
+ }
26
+ if (ch === "\"" || ch === "'") {
27
+ inQuote = ch;
28
+ continue;
29
+ }
30
+ if (ch === "(") {
31
+ if (!depth) {
32
+ if (src.slice(Math.max(0, i - 3), i + 1) === "url(") inUrl = true;
33
+ }
34
+ depth++;
35
+ continue;
36
+ }
37
+ if (ch === ")") {
38
+ depth = Math.max(0, depth - 1);
39
+ if (inUrl && depth === 0) inUrl = false;
40
+ continue;
41
+ }
42
+ if (inUrl) continue;
43
+ if (!depth) {
44
+ if (ch === ",") {
45
+ flush(true, false);
46
+ continue;
47
+ }
48
+ if (ch === "/") {
49
+ const prevIsWhitespace = isWhitespace(src[i - 1]);
50
+ const nextIsWhitespace = isWhitespace(src[i + 1]);
51
+ if (prevIsWhitespace && nextIsWhitespace) {
52
+ pendingSlash = true;
53
+ start = i + 1;
54
+ continue;
55
+ }
56
+ continue;
57
+ }
58
+ if (isWhitespace(ch)) {
59
+ flush(false, false);
60
+ continue;
61
+ }
62
+ }
63
+ }
64
+ flush(false, false);
65
+ }
66
+
67
+ //#endregion
68
+ export { scan };
69
+ //# sourceMappingURL=tokenizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenizer.js","names":[],"sources":["../../src/parser/tokenizer.ts"],"sourcesContent":["export type TokenCallback = (\n token: string,\n isComma: boolean,\n isSlash: boolean,\n precedingChar: string | null,\n) => void;\n\nconst isWhitespace = (ch: string | undefined): boolean =>\n ch === ' ' || ch === '\\n' || ch === '\\t' || ch === '\\r' || ch === '\\f';\n\nexport function scan(src: string, cb: TokenCallback) {\n let depth = 0;\n let inUrl = false;\n let inQuote: string | 0 = 0;\n let start = 0;\n let i = 0;\n // Track if we just saw a standalone slash separator (whitespace before, whitespace after)\n let pendingSlash = false;\n\n const flush = (isComma: boolean, isSlash: boolean) => {\n // If we have a pending slash, emit the part break\n const actualSlash = isSlash || pendingSlash;\n pendingSlash = false;\n\n if (start < i) {\n const prevChar = start > 0 ? src[start - 1] : null;\n cb(src.slice(start, i), isComma, actualSlash, prevChar);\n } else if (isComma) {\n cb('', true, false, null); // empty token followed by comma => group break.\n } else if (actualSlash) {\n cb('', false, true, null); // empty token followed by slash => part break.\n }\n start = i + 1;\n };\n\n for (; i < src.length; i++) {\n const ch = src[i];\n\n // quote mode\n if (inQuote) {\n if (ch === inQuote && src[i - 1] !== '\\\\') inQuote = 0;\n continue;\n }\n if (ch === '\"' || ch === \"'\") {\n inQuote = ch;\n continue;\n }\n\n // paren & url tracking (not inside quotes)\n if (ch === '(') {\n // detect url(\n if (!depth) {\n const maybe = src.slice(Math.max(0, i - 3), i + 1);\n if (maybe === 'url(') inUrl = true;\n }\n depth++;\n continue;\n }\n if (ch === ')') {\n depth = Math.max(0, depth - 1);\n if (inUrl && depth === 0) inUrl = false;\n continue;\n }\n\n if (inUrl) continue; // inside url(...) treat everything as part of token\n\n if (!depth) {\n if (ch === ',') {\n flush(true, false);\n continue;\n }\n // Slash is only a separator when surrounded by whitespace (e.g., \"a / b\")\n // This preserves CSS patterns like \"center/cover\" as single tokens\n if (ch === '/') {\n const prevIsWhitespace = isWhitespace(src[i - 1]);\n const nextIsWhitespace = isWhitespace(src[i + 1]);\n if (prevIsWhitespace && nextIsWhitespace) {\n // Already flushed by whitespace before, mark pending slash\n pendingSlash = true;\n start = i + 1; // skip the slash character\n continue;\n }\n // Not surrounded by whitespace - treat as part of token\n continue;\n }\n if (isWhitespace(ch)) {\n flush(false, false);\n continue;\n }\n }\n }\n flush(false, false); // tail\n}\n"],"mappings":";AAOA,MAAM,gBAAgB,OACpB,OAAO,OAAO,OAAO,QAAQ,OAAO,OAAQ,OAAO,QAAQ,OAAO;AAEpE,SAAgB,KAAK,KAAa,IAAmB;CACnD,IAAI,QAAQ;CACZ,IAAI,QAAQ;CACZ,IAAI,UAAsB;CAC1B,IAAI,QAAQ;CACZ,IAAI,IAAI;CAER,IAAI,eAAe;CAEnB,MAAM,SAAS,SAAkB,YAAqB;EAEpD,MAAM,cAAc,WAAW;AAC/B,iBAAe;AAEf,MAAI,QAAQ,GAAG;GACb,MAAM,WAAW,QAAQ,IAAI,IAAI,QAAQ,KAAK;AAC9C,MAAG,IAAI,MAAM,OAAO,EAAE,EAAE,SAAS,aAAa,SAAS;aAC9C,QACT,IAAG,IAAI,MAAM,OAAO,KAAK;WAChB,YACT,IAAG,IAAI,OAAO,MAAM,KAAK;AAE3B,UAAQ,IAAI;;AAGd,QAAO,IAAI,IAAI,QAAQ,KAAK;EAC1B,MAAM,KAAK,IAAI;AAGf,MAAI,SAAS;AACX,OAAI,OAAO,WAAW,IAAI,IAAI,OAAO,KAAM,WAAU;AACrD;;AAEF,MAAI,OAAO,QAAO,OAAO,KAAK;AAC5B,aAAU;AACV;;AAIF,MAAI,OAAO,KAAK;AAEd,OAAI,CAAC,OAEH;QADc,IAAI,MAAM,KAAK,IAAI,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KACpC,OAAQ,SAAQ;;AAEhC;AACA;;AAEF,MAAI,OAAO,KAAK;AACd,WAAQ,KAAK,IAAI,GAAG,QAAQ,EAAE;AAC9B,OAAI,SAAS,UAAU,EAAG,SAAQ;AAClC;;AAGF,MAAI,MAAO;AAEX,MAAI,CAAC,OAAO;AACV,OAAI,OAAO,KAAK;AACd,UAAM,MAAM,MAAM;AAClB;;AAIF,OAAI,OAAO,KAAK;IACd,MAAM,mBAAmB,aAAa,IAAI,IAAI,GAAG;IACjD,MAAM,mBAAmB,aAAa,IAAI,IAAI,GAAG;AACjD,QAAI,oBAAoB,kBAAkB;AAExC,oBAAe;AACf,aAAQ,IAAI;AACZ;;AAGF;;AAEF,OAAI,aAAa,GAAG,EAAE;AACpB,UAAM,OAAO,MAAM;AACnB;;;;AAIN,OAAM,OAAO,MAAM"}
@@ -0,0 +1,51 @@
1
+ //#region src/parser/types.d.ts
2
+ declare enum Bucket {
3
+ Color = 0,
4
+ Value = 1,
5
+ Mod = 2
6
+ }
7
+ /**
8
+ * A part within a group, representing a slash-separated segment.
9
+ * For example, in `'2px solid #red / 4px'`, there are two parts:
10
+ * - Part 0: `2px solid #red`
11
+ * - Part 1: `4px`
12
+ */
13
+ interface StyleDetailsPart {
14
+ mods: string[];
15
+ values: string[];
16
+ colors: string[];
17
+ all: string[];
18
+ output: string;
19
+ }
20
+ /**
21
+ * A group of style details, representing a comma-separated segment.
22
+ * Contains aggregated values from all parts for backward compatibility,
23
+ * plus the structured `parts` array for handlers that need slash separation.
24
+ */
25
+ interface StyleDetails {
26
+ input: string;
27
+ output: string;
28
+ /** Aggregated mods from all parts (backward compatible) */
29
+ mods: string[];
30
+ /** Aggregated values from all parts (backward compatible) */
31
+ values: string[];
32
+ /** Aggregated colors from all parts (backward compatible) */
33
+ colors: string[];
34
+ /** Aggregated all tokens from all parts (backward compatible) */
35
+ all: string[];
36
+ /** Slash-separated parts within this group */
37
+ parts: StyleDetailsPart[];
38
+ }
39
+ interface ProcessedStyle {
40
+ output: string;
41
+ groups: StyleDetails[];
42
+ }
43
+ type UnitHandler = (scalar: number) => string;
44
+ interface ParserOptions {
45
+ funcs?: Record<string, (parsed: StyleDetails[]) => string>;
46
+ units?: Record<string, string | UnitHandler>;
47
+ cacheSize?: number;
48
+ }
49
+ //#endregion
50
+ export { Bucket, ParserOptions, ProcessedStyle, StyleDetails, StyleDetailsPart, UnitHandler };
51
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,46 @@
1
+ //#region src/parser/types.ts
2
+ let Bucket = /* @__PURE__ */ function(Bucket) {
3
+ Bucket[Bucket["Color"] = 0] = "Color";
4
+ Bucket[Bucket["Value"] = 1] = "Value";
5
+ Bucket[Bucket["Mod"] = 2] = "Mod";
6
+ return Bucket;
7
+ }({});
8
+ const makeEmptyPart = () => ({
9
+ mods: [],
10
+ values: [],
11
+ colors: [],
12
+ all: [],
13
+ output: ""
14
+ });
15
+ const makeEmptyDetails = () => ({
16
+ input: "",
17
+ output: "",
18
+ mods: [],
19
+ values: [],
20
+ colors: [],
21
+ all: [],
22
+ parts: []
23
+ });
24
+ const finalizePart = (p) => {
25
+ p.output = p.all.join(" ");
26
+ return p;
27
+ };
28
+ /**
29
+ * Aggregate parts into a StyleDetails group.
30
+ * Combines all parts' arrays into group-level arrays for backward compatibility.
31
+ */
32
+ const finalizeGroup = (d, parts) => {
33
+ d.parts = parts;
34
+ for (const part of parts) {
35
+ d.mods.push(...part.mods);
36
+ d.values.push(...part.values);
37
+ d.colors.push(...part.colors);
38
+ d.all.push(...part.all);
39
+ }
40
+ d.output = parts.map((p) => p.output).join(" / ");
41
+ return d;
42
+ };
43
+
44
+ //#endregion
45
+ export { Bucket, finalizeGroup, finalizePart, makeEmptyDetails, makeEmptyPart };
46
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","names":[],"sources":["../../src/parser/types.ts"],"sourcesContent":["export enum Bucket {\n Color,\n Value,\n Mod,\n}\n\n/**\n * A part within a group, representing a slash-separated segment.\n * For example, in `'2px solid #red / 4px'`, there are two parts:\n * - Part 0: `2px solid #red`\n * - Part 1: `4px`\n */\nexport interface StyleDetailsPart {\n mods: string[];\n values: string[];\n colors: string[];\n all: string[];\n output: string;\n}\n\n/**\n * A group of style details, representing a comma-separated segment.\n * Contains aggregated values from all parts for backward compatibility,\n * plus the structured `parts` array for handlers that need slash separation.\n */\nexport interface StyleDetails {\n input: string;\n output: string;\n /** Aggregated mods from all parts (backward compatible) */\n mods: string[];\n /** Aggregated values from all parts (backward compatible) */\n values: string[];\n /** Aggregated colors from all parts (backward compatible) */\n colors: string[];\n /** Aggregated all tokens from all parts (backward compatible) */\n all: string[];\n /** Slash-separated parts within this group */\n parts: StyleDetailsPart[];\n}\n\nexport interface ProcessedStyle {\n output: string;\n groups: StyleDetails[];\n}\n\nexport type UnitHandler = (scalar: number) => string;\n\nexport interface ParserOptions {\n funcs?: Record<string, (parsed: StyleDetails[]) => string>;\n units?: Record<string, string | UnitHandler>;\n cacheSize?: number;\n}\n\nexport const makeEmptyPart = (): StyleDetailsPart => ({\n mods: [],\n values: [],\n colors: [],\n all: [],\n output: '',\n});\n\nexport const makeEmptyDetails = (): StyleDetails => ({\n input: '',\n output: '',\n mods: [],\n values: [],\n colors: [],\n all: [],\n parts: [],\n});\n\nexport const finalizePart = (p: StyleDetailsPart): StyleDetailsPart => {\n p.output = p.all.join(' ');\n return p;\n};\n\n/**\n * Aggregate parts into a StyleDetails group.\n * Combines all parts' arrays into group-level arrays for backward compatibility.\n */\nexport const finalizeGroup = (\n d: StyleDetails,\n parts: StyleDetailsPart[],\n): StyleDetails => {\n // Store parts\n d.parts = parts;\n\n // Aggregate all parts into group-level arrays\n for (const part of parts) {\n d.mods.push(...part.mods);\n d.values.push(...part.values);\n d.colors.push(...part.colors);\n d.all.push(...part.all);\n }\n\n // Join parts' outputs with ' / ' for the group output\n d.output = parts.map((p) => p.output).join(' / ');\n\n return d;\n};\n"],"mappings":";AAAA,IAAY,0CAAL;AACL;AACA;AACA;;;AAkDF,MAAa,uBAAyC;CACpD,MAAM,EAAE;CACR,QAAQ,EAAE;CACV,QAAQ,EAAE;CACV,KAAK,EAAE;CACP,QAAQ;CACT;AAED,MAAa,0BAAwC;CACnD,OAAO;CACP,QAAQ;CACR,MAAM,EAAE;CACR,QAAQ,EAAE;CACV,QAAQ,EAAE;CACV,KAAK,EAAE;CACP,OAAO,EAAE;CACV;AAED,MAAa,gBAAgB,MAA0C;AACrE,GAAE,SAAS,EAAE,IAAI,KAAK,IAAI;AAC1B,QAAO;;;;;;AAOT,MAAa,iBACX,GACA,UACiB;AAEjB,GAAE,QAAQ;AAGV,MAAK,MAAM,QAAQ,OAAO;AACxB,IAAE,KAAK,KAAK,GAAG,KAAK,KAAK;AACzB,IAAE,OAAO,KAAK,GAAG,KAAK,OAAO;AAC7B,IAAE,OAAO,KAAK,GAAG,KAAK,OAAO;AAC7B,IAAE,IAAI,KAAK,GAAG,KAAK,IAAI;;AAIzB,GAAE,SAAS,MAAM,KAAK,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM;AAEjD,QAAO"}
@@ -0,0 +1,134 @@
1
+ //#region src/pipeline/conditions.d.ts
2
+ /**
3
+ * ConditionNode Types and Helpers
4
+ *
5
+ * Core data structures for representing style conditions as an abstract syntax tree.
6
+ * Used throughout the pipeline for parsing, simplification, and CSS generation.
7
+ */
8
+ /**
9
+ * Base interface for all state conditions (leaf nodes)
10
+ */
11
+ interface BaseStateCondition {
12
+ kind: 'state';
13
+ negated: boolean;
14
+ raw: string;
15
+ uniqueId: string;
16
+ }
17
+ /**
18
+ * Modifier condition: [data-attr] or [data-attr="value"]
19
+ */
20
+ interface ModifierCondition extends BaseStateCondition {
21
+ type: 'modifier';
22
+ attribute: string;
23
+ value?: string;
24
+ operator?: '=' | '^=' | '$=' | '*=';
25
+ }
26
+ /**
27
+ * Pseudo-class condition: :hover, :focus-visible
28
+ */
29
+ interface PseudoCondition extends BaseStateCondition {
30
+ type: 'pseudo';
31
+ pseudo: string;
32
+ }
33
+ /**
34
+ * Numeric bound for dimension queries
35
+ */
36
+ interface NumericBound {
37
+ value: string;
38
+ valueNumeric: number | null;
39
+ inclusive: boolean;
40
+ }
41
+ /**
42
+ * Media query condition
43
+ */
44
+ interface MediaCondition extends BaseStateCondition {
45
+ type: 'media';
46
+ subtype: 'dimension' | 'feature' | 'type';
47
+ dimension?: 'width' | 'height' | 'inline-size' | 'block-size';
48
+ lowerBound?: NumericBound;
49
+ upperBound?: NumericBound;
50
+ feature?: string;
51
+ featureValue?: string;
52
+ mediaType?: 'print' | 'screen' | 'all' | 'speech';
53
+ }
54
+ /**
55
+ * Container query condition
56
+ */
57
+ interface ContainerCondition extends BaseStateCondition {
58
+ type: 'container';
59
+ subtype: 'dimension' | 'style' | 'raw';
60
+ containerName?: string;
61
+ dimension?: 'width' | 'height' | 'inline-size' | 'block-size';
62
+ lowerBound?: NumericBound;
63
+ upperBound?: NumericBound;
64
+ property?: string;
65
+ propertyValue?: string;
66
+ rawCondition?: string;
67
+ }
68
+ /**
69
+ * Root state condition: @root(theme=dark)
70
+ */
71
+ interface RootCondition extends BaseStateCondition {
72
+ type: 'root';
73
+ innerCondition: ConditionNode;
74
+ }
75
+ /**
76
+ * Parent state condition: @parent(hovered), @parent(theme=dark, >)
77
+ */
78
+ interface ParentCondition extends BaseStateCondition {
79
+ type: 'parent';
80
+ innerCondition: ConditionNode;
81
+ direct: boolean;
82
+ }
83
+ /**
84
+ * Own state condition: @own(hovered)
85
+ */
86
+ interface OwnCondition extends BaseStateCondition {
87
+ type: 'own';
88
+ innerCondition: ConditionNode;
89
+ }
90
+ /**
91
+ * Starting style condition: @starting
92
+ */
93
+ interface StartingCondition extends BaseStateCondition {
94
+ type: 'starting';
95
+ }
96
+ /**
97
+ * Supports query condition: @supports(display: grid), @supports($, :has(*))
98
+ */
99
+ interface SupportsCondition extends BaseStateCondition {
100
+ type: 'supports';
101
+ subtype: 'feature' | 'selector';
102
+ condition: string;
103
+ }
104
+ /**
105
+ * Union of all state condition types
106
+ */
107
+ type StateCondition = ModifierCondition | PseudoCondition | MediaCondition | ContainerCondition | RootCondition | ParentCondition | OwnCondition | StartingCondition | SupportsCondition;
108
+ /**
109
+ * Compound node: combines conditions with AND/OR
110
+ */
111
+ interface CompoundCondition {
112
+ kind: 'compound';
113
+ operator: 'AND' | 'OR';
114
+ children: ConditionNode[];
115
+ }
116
+ /**
117
+ * True condition (matches everything)
118
+ */
119
+ interface TrueCondition {
120
+ kind: 'true';
121
+ }
122
+ /**
123
+ * False condition (matches nothing - skip this rule)
124
+ */
125
+ interface FalseCondition {
126
+ kind: 'false';
127
+ }
128
+ /**
129
+ * Union of all condition node types
130
+ */
131
+ type ConditionNode = StateCondition | CompoundCondition | TrueCondition | FalseCondition;
132
+ //#endregion
133
+ export { ConditionNode };
134
+ //# sourceMappingURL=conditions.d.ts.map