cssints 0.1.0 → 0.3.0

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 (161) hide show
  1. package/README.md +107 -53
  2. package/dist/check.mjs +2 -2
  3. package/dist/{contrast-BUKVao74.mjs → contrast-B49XCnVX.mjs} +2 -2
  4. package/dist/devtools-link-D2YxsJKZ.mjs +94 -0
  5. package/dist/devtools-link.d.mts +55 -0
  6. package/dist/devtools-link.mjs +2 -0
  7. package/dist/group-common-9zpBxfUF.d.mts +1 -0
  8. package/dist/group-types-9ttphdku.d.mts +55 -0
  9. package/dist/groups/baseline-2015/with-downstream.d.mts +81 -0
  10. package/dist/groups/baseline-2015.d.mts +291 -0
  11. package/dist/groups/baseline-2016/with-downstream.d.mts +86 -0
  12. package/dist/groups/baseline-2016.d.mts +310 -0
  13. package/dist/groups/baseline-2017/with-downstream.d.mts +94 -0
  14. package/dist/groups/baseline-2017.d.mts +365 -0
  15. package/dist/groups/baseline-2018/with-downstream.d.mts +94 -0
  16. package/dist/groups/baseline-2018.d.mts +368 -0
  17. package/dist/groups/baseline-2019/with-downstream.d.mts +97 -0
  18. package/dist/groups/baseline-2019.d.mts +375 -0
  19. package/dist/groups/baseline-2020/with-downstream.d.mts +112 -0
  20. package/dist/groups/baseline-2020.d.mts +480 -0
  21. package/dist/groups/baseline-2021/with-downstream.d.mts +125 -0
  22. package/dist/groups/baseline-2021.d.mts +536 -0
  23. package/dist/groups/baseline-2022/with-downstream.d.mts +126 -0
  24. package/dist/groups/baseline-2022.d.mts +562 -0
  25. package/dist/groups/baseline-2023/with-downstream.d.mts +120 -0
  26. package/dist/groups/baseline-2023.d.mts +606 -0
  27. package/dist/groups/baseline-2024/with-downstream.d.mts +627 -0
  28. package/dist/groups/baseline-2024.d.mts +632 -0
  29. package/dist/groups/baseline-2025/with-downstream.d.mts +628 -0
  30. package/dist/groups/baseline-2025.d.mts +640 -0
  31. package/dist/groups/baseline-2026/with-downstream.d.mts +3 -0
  32. package/dist/groups/baseline-2026.d.mts +3 -0
  33. package/dist/groups/compositing-2.d.mts +20 -0
  34. package/dist/groups/css-align-3.d.mts +29 -0
  35. package/dist/groups/css-anchor-position-1.d.mts +49 -0
  36. package/dist/groups/css-anchor-position-2.d.mts +50 -0
  37. package/dist/groups/css-animations-1.d.mts +28 -0
  38. package/dist/groups/css-animations-2.d.mts +29 -0
  39. package/dist/groups/css-backgrounds-3.d.mts +27 -0
  40. package/dist/groups/css-backgrounds-4.d.mts +29 -0
  41. package/dist/groups/css-borders-4.d.mts +95 -0
  42. package/dist/groups/css-box-4.d.mts +38 -0
  43. package/dist/groups/css-break-4.d.mts +23 -0
  44. package/dist/groups/css-cascade-5.d.mts +18 -0
  45. package/dist/groups/css-cascade-6.d.mts +18 -0
  46. package/dist/groups/css-color-4.d.mts +29 -0
  47. package/dist/groups/css-color-5.d.mts +32 -0
  48. package/dist/groups/css-color-6.d.mts +32 -0
  49. package/dist/groups/css-color-adjust-1.d.mts +20 -0
  50. package/dist/groups/css-color-hdr-1.d.mts +19 -0
  51. package/dist/groups/css-conditional-3.d.mts +17 -0
  52. package/dist/groups/css-conditional-4.d.mts +17 -0
  53. package/dist/groups/css-conditional-5.d.mts +22 -0
  54. package/dist/groups/css-contain-2.d.mts +19 -0
  55. package/dist/groups/css-content-3.d.mts +23 -0
  56. package/dist/groups/css-counter-styles-3.d.mts +16 -0
  57. package/dist/groups/css-display-4.d.mts +22 -0
  58. package/dist/groups/css-easing-2.d.mts +18 -0
  59. package/dist/groups/css-env-1.d.mts +16 -0
  60. package/dist/groups/css-flexbox-1.d.mts +24 -0
  61. package/dist/groups/css-fonts-4.d.mts +46 -0
  62. package/dist/groups/css-fonts-5.d.mts +44 -0
  63. package/dist/groups/css-forms-1.d.mts +19 -0
  64. package/dist/groups/css-gaps-1.d.mts +21 -0
  65. package/dist/groups/css-gcpm-3.d.mts +20 -0
  66. package/dist/groups/css-gcpm-4.d.mts +20 -0
  67. package/dist/groups/css-grid-2.d.mts +34 -0
  68. package/dist/groups/css-grid-3.d.mts +34 -0
  69. package/dist/groups/css-images-3.d.mts +25 -0
  70. package/dist/groups/css-images-4.d.mts +32 -0
  71. package/dist/groups/css-images-5.d.mts +33 -0
  72. package/dist/groups/css-inline-3.d.mts +28 -0
  73. package/dist/groups/css-lists-3.d.mts +26 -0
  74. package/dist/groups/css-logical-1.d.mts +35 -0
  75. package/dist/groups/css-masking-1.d.mts +37 -0
  76. package/dist/groups/css-multicol-2.d.mts +24 -0
  77. package/dist/groups/css-overflow-3.d.mts +28 -0
  78. package/dist/groups/css-overflow-4.d.mts +29 -0
  79. package/dist/groups/css-overflow-5.d.mts +31 -0
  80. package/dist/groups/css-overscroll-1.d.mts +22 -0
  81. package/dist/groups/css-page-3.d.mts +18 -0
  82. package/dist/groups/css-page-floats-3.d.mts +19 -0
  83. package/dist/groups/css-position-3.d.mts +29 -0
  84. package/dist/groups/css-position-4.d.mts +30 -0
  85. package/dist/groups/css-rhythm-1.d.mts +18 -0
  86. package/dist/groups/css-round-display-1.d.mts +16 -0
  87. package/dist/groups/css-ruby-1.d.mts +21 -0
  88. package/dist/groups/css-scroll-anchoring-1.d.mts +18 -0
  89. package/dist/groups/css-scroll-snap-1.d.mts +42 -0
  90. package/dist/groups/css-scroll-snap-2.d.mts +43 -0
  91. package/dist/groups/css-scrollbars-1.d.mts +19 -0
  92. package/dist/groups/css-shapes-1.d.mts +27 -0
  93. package/dist/groups/css-shapes-2.d.mts +27 -0
  94. package/dist/groups/css-size-adjust-1.d.mts +18 -0
  95. package/dist/groups/css-sizing-3.d.mts +34 -0
  96. package/dist/groups/css-sizing-4.d.mts +33 -0
  97. package/dist/groups/css-speech-1.d.mts +18 -0
  98. package/dist/groups/css-tables-3.d.mts +22 -0
  99. package/dist/groups/css-text-3.d.mts +36 -0
  100. package/dist/groups/css-text-4.d.mts +40 -0
  101. package/dist/groups/css-text-decor-3.d.mts +30 -0
  102. package/dist/groups/css-text-decor-4.d.mts +31 -0
  103. package/dist/groups/css-transforms-1.d.mts +31 -0
  104. package/dist/groups/css-transforms-2.d.mts +48 -0
  105. package/dist/groups/css-transitions-1.d.mts +22 -0
  106. package/dist/groups/css-transitions-2.d.mts +23 -0
  107. package/dist/groups/css-ui-4.d.mts +35 -0
  108. package/dist/groups/css-values-4.d.mts +38 -0
  109. package/dist/groups/css-values-5.d.mts +43 -0
  110. package/dist/groups/css-variables-2.d.mts +6 -0
  111. package/dist/groups/css-view-transitions-2.d.mts +20 -0
  112. package/dist/groups/css-viewport.d.mts +18 -0
  113. package/dist/groups/css-will-change-1.d.mts +18 -0
  114. package/dist/groups/css-writing-modes-4.d.mts +22 -0
  115. package/dist/groups/css2.d.mts +19 -0
  116. package/dist/groups/fill-stroke-3.d.mts +27 -0
  117. package/dist/groups/filter-effects-1.d.mts +32 -0
  118. package/dist/groups/filter-effects-2.d.mts +33 -0
  119. package/dist/groups/limited-availability.d.mts +2 -0
  120. package/dist/groups/mediaqueries-4.d.mts +16 -0
  121. package/dist/groups/mediaqueries-5.d.mts +16 -0
  122. package/dist/groups/motion-1.d.mts +24 -0
  123. package/dist/groups/newly-available/with-downstream.d.mts +632 -0
  124. package/dist/groups/newly-available.d.mts +631 -0
  125. package/dist/groups/not-discouraged.d.mts +727 -0
  126. package/dist/groups/scroll-animations-1.d.mts +30 -0
  127. package/dist/groups/selectors-4.d.mts +54 -0
  128. package/dist/groups/selectors-5.d.mts +54 -0
  129. package/dist/groups/widely-available/with-downstream.d.mts +121 -0
  130. package/dist/groups/widely-available.d.mts +616 -0
  131. package/dist/index.d.mts +19 -5
  132. package/dist/index.mjs +166 -14
  133. package/dist/instrument-BqIZpbIU.mjs +3956 -0
  134. package/dist/{lowered-CeoXbm0P.mjs → lowered-aJVapQT6.mjs} +1 -1
  135. package/dist/{node-CdhAGmF3.d.mts → node-OJ_w_Usj.d.mts} +4 -0
  136. package/dist/plugin-types.d.mts +8 -1
  137. package/dist/plugin.d.mts +2 -2
  138. package/dist/plugin.mjs +8 -1
  139. package/dist/{registry-n9JCX4pl.mjs → registry-BUSEO32-.mjs} +8 -1
  140. package/dist/runtime-Dt4Tm0Q7.d.mts +19 -0
  141. package/dist/runtime.d.mts +1 -1
  142. package/dist/runtime.mjs +6 -2
  143. package/dist/{scope-oWEaWE9n.d.mts → scope-INuJD4RT.d.mts} +18 -5
  144. package/dist/{sheet-CO7a-mdA.mjs → sheet-BeHdq4xt.mjs} +2 -1
  145. package/dist/surface.d.mts +1 -1
  146. package/dist/{theme-BGEbFAYh.mjs → theme-SlQ73rFL.mjs} +31 -8
  147. package/dist/{theme-types-DHdtTZhz.d.mts → theme-types-Bqv0Ggz_.d.mts} +11 -6
  148. package/dist/tui-types.d.mts +1 -1
  149. package/dist/tui.d.mts +1 -8
  150. package/dist/tui.mjs +35 -7
  151. package/dist/types.d.mts +1 -1
  152. package/dist/vite.d.mts +20 -2
  153. package/dist/vite.mjs +90 -41
  154. package/docs/API.md +519 -251
  155. package/package.json +10 -2
  156. package/skills/cssints/SKILL.md +12 -9
  157. package/skills/cssints/references/errors.md +8 -7
  158. package/skills/cssints-plugin/SKILL.md +3 -1
  159. package/dist/instrument-Bdtk2INz.mjs +0 -172
  160. package/dist/lib-2OEIfPAE.d.mts +0 -9
  161. package/dist/runtime-CTvuM-Hm.d.mts +0 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cssints",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "CSS in TypeScript: typed css.* calls compiled to atomic CSS at build time (a Vite plugin)",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -53,10 +53,18 @@
53
53
  "./tui": {
54
54
  "types": "./dist/tui-types.d.mts",
55
55
  "default": "./dist/tui.mjs"
56
+ },
57
+ "./devtools-link": {
58
+ "types": "./dist/devtools-link.d.mts",
59
+ "default": "./dist/devtools-link.mjs"
60
+ },
61
+ "./*": {
62
+ "types": "./dist/groups/*.d.mts",
63
+ "default": "./dist/index.mjs"
56
64
  }
57
65
  },
58
66
  "dependencies": {
59
- "@cssints/css-grammar": "^0.1.0",
67
+ "@cssints/css-grammar": "^0.3.0",
60
68
  "culori": "^4.0.2",
61
69
  "effect": "4.0.0",
62
70
  "happy-dom": "^20.14.5",
@@ -3,7 +3,7 @@ name: cssints
3
3
  description: >-
4
4
  Write, review and fix styles in a project that uses cssints, the CSS-in-TypeScript compiler (a Vite plugin that
5
5
  runs css.* calls at build time and replaces them with atomic class strings). Load it when code imports from
6
- "cssints" with { type: "cssints" }, uses cn(), cx(), cv(), css.* members, media()/hover()/container()/within(),
6
+ "cssints" with { type: "cssints" }, uses cn(), cv(), css.* members, media()/hover()/container()/within(),
7
7
  createTokens, createGlobalTheme, check.contrast, or an @cssints/* package (layout, motion, fluid, fonts, reset,
8
8
  tokens, icons, ...), and when a build fails with a "cssints:" message such as "must be known at build time",
9
9
  "without the attribute", "unexpected ... expected <...>", "overlap without one containing the other" or
@@ -15,7 +15,7 @@ description: >-
15
15
  Every `css.*` call runs at build time in Vite's Module Runner and is replaced by a class string. The values are
16
16
  checked against the CSS grammars (mdn-data) twice: in the types, where the call is, and again by the build, with the
17
17
  file and the place of the call. One sheet, `virtual:cssints.css`, holds every rule once, in `@layer`s. The browser
18
- gets class strings, `cx` and the few lines behind `cv`. The reference is `docs/API.md` of the cssints repository; the
18
+ gets class strings and the few lines behind `cn` with runtime arguments and `cv`. The reference is `docs/API.md` of the cssints repository; the
19
19
  parts below are what you need most of the time.
20
20
 
21
21
  If the cssints MCP server is configured, prefer it for checks: `check_declaration` (is this value valid, and the
@@ -51,7 +51,6 @@ export default {
51
51
  ## The import attribute
52
52
 
53
53
  ```ts
54
- import { cx } from "cssints"; // runtime: the only member without the attribute
55
54
  import { cn, cv, hover, media, p } from "cssints" with { type: "cssints" }; // build time
56
55
  import * as css from "cssints" with { type: "cssints" }; // the same, as a namespace
57
56
  import { stack } from "./stack.ts" with { type: "cssints" }; // your own helper module, run at build time
@@ -68,7 +67,7 @@ import { stack } from "./stack.ts" with { type: "cssints" }; // your own helper
68
67
  where the call is evaluated`. The types do not catch it. Choose at runtime between styles made at build time:
69
68
 
70
69
  ```tsx
71
- <div className={cx(base, on && p(4))} /> // a condition: cx skips falsy values
70
+ <div className={cn(base, on && p(4))} /> // a condition: cn joins it at runtime, p(4) is a class already
72
71
  <button className={button({ size })} /> // a cv() variant
73
72
  <div style={style(token.set(accent, "#dc2626"))} /> // a token set inline (static values)
74
73
  <div style={{ "--accent": value }} /> // a dynamic value: a plain style prop
@@ -93,12 +92,16 @@ the run does not reach (`false && p(4)`, a branch) still gets its class string.
93
92
  - `firstThatWorks("100dvh", "100vh")` is a value with fallbacks in one class.
94
93
  - `keyframes({ from: opacity(0), to: opacity(1) })` returns a name for `animation(fade, "200ms")`.
95
94
 
96
- ## Merging: cn, cx, cv
95
+ ## Merging: cn, cv
97
96
 
98
97
  - `cn(...)` merges at build time into one string; the later of one property wins (`cn(p(4), p(2))` is `p(2)`). A
99
98
  longhand beats its shorthand whatever the order. Two properties that overlap without one containing the other
100
99
  (`borderTop` and `borderColor`, `marginLeft` and `marginInline`) are a build error: set one, or the longhands.
101
- - `cx(...)` joins strings at runtime (skips falsy values, flattens arrays; no clsx objects). It sees no conflicts.
100
+ - `cn(...)` takes runtime values too: `cn(base, on && p(4), props.class)`. An argument that names a parameter, a prop
101
+ or state, a string, or a call of something that is not a `css.*` member is joined at runtime (falsy values skipped,
102
+ arrays flattened; no clsx objects); the styles in it are class strings made at build time, and while a style
103
+ is active it replaces the classes it overrides (`cn(p(2), on && p(4))` is `p-4` when `on`, else `p-2`). A class
104
+ string such as `props.class` is only appended. `cx` is gone: importing it is a build error.
102
105
  - `cv({ base, variants, defaultVariants, compoundVariants })` is the function you call; props are typed. A variant
103
106
  wins over the base, a compound (`{ size: "lg", tone: "loud", class: p(6) }`) over both. Values are `css.*` styles,
104
107
  never CSS strings.
@@ -157,7 +160,7 @@ DTCG JSON, Figma exports, references `{color.accent}`, derived values and layers
157
160
  ## Plugin packages: which one
158
161
 
159
162
  Import them with the attribute, except `@cssints/tokens` and `@cssints/ramp` (plain data for `createTokens`). A
160
- member returns a class string (or a value) that goes into `cn()`/`cx()`. Details and gotchas:
163
+ member returns a class string (or a value) that goes into `cn()`. Details and gotchas:
161
164
  [references/plugins.md](references/plugins.md).
162
165
 
163
166
  | Need | Package |
@@ -191,8 +194,8 @@ the call. The common ones, with fixes: [references/errors.md](references/errors.
191
194
 
192
195
  ## Rules of thumb
193
196
 
194
- - Make every style at module level or in a helper module; choose between them at runtime with `cx`, `cv` or tokens.
195
- - Prefer `cn()` to `cx()` when the parts are fixed: it is checked for conflicts and leaves nothing at runtime.
197
+ - Make every style at module level or in a helper module; choose between them at runtime with `cn(base, on && p(4))`, `cv` or tokens.
198
+ - A `cn()` with no runtime argument is checked for conflicts and leaves nothing at runtime; keep what is fixed in it.
196
199
  - Prefer a token and a theme to a second style for each colour mode.
197
200
  - Write `check.contrast` for each text/background pair you use; it checks every theme.
198
201
  - A support warning is not an error: the value works where the targets have it. LightningCSS lowers what it can
@@ -7,11 +7,12 @@ contrast, ranges in some positions, `supports()` property names. The messages be
7
7
 
8
8
  ## Imports and build-time values
9
9
 
10
- | Message | Meaning and fix |
11
- | ------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
12
- | `<file> imports build-time p from "cssints" without the attribute. Import it as: … with { type: "cssints" }` | Every member but `cx` runs at build time. Add `with { type: "cssints" }` to that import (keep `cx` in a plain import, or in the same one). |
13
- | `css arguments must be known at build time: n is not defined where the call is evaluated (a parameter, a prop or state)` | The call reads a runtime value. Make the styles at build time and choose at runtime: `cx(on && p(4))`, a `cv()` variant, or a token set in `style={...}`. Also when a local shadows a global (`open`, `name`). |
14
- | `imports _cv from "cssints", which is gone` | Old code: `cv({ ... })` is the function now. Drop `_cv(` and its closing bracket. |
10
+ | Message | Meaning and fix |
11
+ | ------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
12
+ | `<file> imports build-time p from "cssints" without the attribute. Import it as: … with { type: "cssints" }` | Every member runs at build time. Add `with { type: "cssints" }` to that import. |
13
+ | `css arguments must be known at build time: n is not defined where the call is evaluated (a parameter, a prop or state)` | The call reads a runtime value. Make the styles at build time and choose at runtime: `cn(base, on && p(4))`, a `cv()` variant, or a token set in `style={...}`. Also when a local shadows a global (`open`, `name`). |
14
+ | `imports cx from "cssints", which is gone: cn(...) takes runtime values now` | Old code: `cx(a, on && b)` is `cn(a, on && b)` now (cn from `"cssints" with { type: "cssints" }`). `cx(p(4), p(2))` kept both; `cn` keeps `p(2)`. |
15
+ | `imports _cv from "cssints", which is gone` | Old code: `cv({ ... })` is the function now. Drop `_cv(` and its closing bracket. |
15
16
 
16
17
  ## Grammar errors
17
18
 
@@ -36,7 +37,7 @@ reverse); trust the build's message and, with the MCP server, `check_declaration
36
37
  | Message | Fix |
37
38
  | -------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
38
39
  | `flex() has no .padding(); it chains direction, wrap, flow, alignItems, …` | A chain has only its container properties. Merge the rest: `cn(flex().gap(2), p(4))`. |
39
- | `plain styles do not chain (.gap); merge them with cn(...) or cx(...)` | `flex("1")` (with an argument) is the shorthand property, a plain style. |
40
+ | `plain styles do not chain (.gap); merge them with cn(...)` | `flex("1")` (with an argument) is the shorthand property, a plain style. |
40
41
  | `sticky().top() is used twice` (and other members: a method is used once) | Each method of a chain once. Under a condition, a second chain is fine: `hover(x().y(...))`. |
41
42
 
42
43
  ## Conflicts
@@ -49,7 +50,7 @@ reverse); trust the build's message and, with the MCP server, `check_declaration
49
50
  | `layout: kernel stack-core sets display, flex-direction, gap (this style also sets display)` | A plugin member and a property its kernel sets, in one `cn()`. Use the member's method (`stack().gap(4)`), or drop the property. |
50
51
  | `frame: frame() sets padding, margin, border-radius and the border: use its methods (this style also sets padding)` | The same, with the plugin's own message. |
51
52
 
52
- `cx()` joins strings at runtime and checks nothing: a conflict across `cx()` arguments is not reported.
53
+ A runtime argument of `cn()` is joined at runtime; a style in it replaces what it overrides, and `props.class` is only appended, so a conflict with it is not reported.
53
54
 
54
55
  ## Conditions
55
56
 
@@ -14,7 +14,7 @@ description: >-
14
14
  A plugin is a module that exports the members of `scope(name, table).build(impl).export()` from `cssints/plugin`.
15
15
  The table says what the plugin has; the members are typed from it (no types file). User code imports the plugin with
16
16
  `with { type: "cssints" }`; there is no registration. In user code a member is a class string (or a CSS value), so it
17
- goes into `cn()`, `cx()` and conditions. Everything runs at build time in Vite's Module Runner. Read the user skill
17
+ goes into `cn()` and conditions. Everything runs at build time in Vite's Module Runner. Read the user skill
18
18
  `cssints` first for the styles themselves; the full reference is the "Plugins" section of `docs/API.md`.
19
19
 
20
20
  If the cssints MCP server is configured, prefer `compile` to see a fixture's classes, sheet, errors and warnings,
@@ -135,6 +135,8 @@ lacks a key.
135
135
  rules or styles only when needed (`stuck()` adds its attribute rules only then).
136
136
  - `dependsOn(path)`: call it for every file the plugin reads (an image, an SVG, a font). In dev an edit of the file
137
137
  runs the modules that read it again; in `vite build --watch` it is a watched file.
138
+ - `inGroup(group, property, value)`: is a declaration in an export group (`widely-available`, `baseline-2022`, ...)?
139
+ A plugin with a variant per group emits only what passes (`@cssints/reset/widely-available`). Selectors are not checked.
138
140
 
139
141
  ## Errors
140
142
 
@@ -1,172 +0,0 @@
1
- import { u as ImportError } from "./registry-n9JCX4pl.mjs";
2
- import { Effect, Formatter, Predicate } from "effect";
3
- import { parseSync } from "oxc-parser";
4
- import MagicString from "magic-string";
5
- //#region src/instrument.ts
6
- const RUNTIME = "cssints";
7
- const CV_CALL = "__cv(";
8
- const rootIdent = (n) => n.type === "Identifier" ? n.name : n.type === "MemberExpression" ? rootIdent(n.object) : n.type === "CallExpression" ? rootIdent(n.callee) : null;
9
- const RUNTIME_ONLY = /* @__PURE__ */ new Set(["cx"]);
10
- const TYPED_OM = /* @__PURE__ */ new Set([
11
- "CSS",
12
- "CSSStyleValue",
13
- "CSSUnitValue",
14
- "CSSColorValue",
15
- "CSSImageValue"
16
- ]);
17
- const nameOf = (m) => m.type === "Identifier" ? m.name : m.value;
18
- const isSiteImport = (s) => s.attributes.some((a) => (a.key.type === "Identifier" ? a.key.name : a.key.value) === "type" && a.value.value === "cssints");
19
- const importedName = (x) => x.type === "ImportSpecifier" ? nameOf(x.imported) : null;
20
- const isRuntime = (d, x) => d.source.value === "cssints" && x.type === "ImportSpecifier" && RUNTIME_ONLY.has(nameOf(x.imported));
21
- const keptImport = (d, code) => {
22
- const names = d.specifiers.filter((x) => isRuntime(d, x)).map((x) => code.slice(x.start, x.end));
23
- return names.length ? `import { ${names.join(", ")} } from ${Formatter.formatJson(RUNTIME)};` : "";
24
- };
25
- const findCssImport = Effect.fnUntraced(function* (program, code, id, client) {
26
- const plain = (name) => RUNTIME_ONLY.has(name) || !client && TYPED_OM.has(name);
27
- const locals = /* @__PURE__ */ new Set();
28
- const decls = [];
29
- for (const s of program.body) {
30
- if (s.type !== "ImportDeclaration") continue;
31
- const old = s.source.value === "cssints" && s.specifiers.find((x) => importedName(x) === "_cv");
32
- if (old) return yield* new ImportError({
33
- message: `cssints: ${id} imports _cv from "cssints", which is gone: cv({ ... }) is the function now. Write const button = cv({ base, variants }) (cv from "cssints" with { type: "cssints" }), drop _cv, and call button({ size: "lg" })`,
34
- file: id,
35
- offset: old.start
36
- });
37
- if (isSiteImport(s)) {
38
- decls.push(s);
39
- s.specifiers.forEach((x) => isRuntime(s, x) || locals.add(x.local.name));
40
- } else if (s.source.value === "cssints" && s.importKind !== "type") {
41
- const bad = s.specifiers.filter((x) => x.type !== "ImportSpecifier" || x.importKind !== "type" && !plain(importedName(x) ?? ""));
42
- if (!bad.length) continue;
43
- const names = bad.map((x) => code.slice(x.start, x.end));
44
- const fix = bad[0].type === "ImportNamespaceSpecifier" ? names[0] : `{ ${names.join(", ")} }`;
45
- return yield* new ImportError({
46
- message: `cssints: ${id} imports build-time ${names.join(", ")} from "cssints" without the attribute. Import it as: import ${fix} from "cssints" with { type: "cssints" }; (only cx is runtime)`,
47
- file: id,
48
- offset: s.start
49
- });
50
- }
51
- }
52
- return locals.size ? {
53
- locals,
54
- decls
55
- } : null;
56
- });
57
- const CONDITIONS = /* @__PURE__ */ new Set([
58
- "media",
59
- "container",
60
- "supports",
61
- "attr",
62
- "within"
63
- ]);
64
- const boundNames = (id, out) => {
65
- if (!id) return;
66
- if (id.type === "Identifier") out.add(id.name);
67
- else if (id.type === "ArrayPattern") id.elements.forEach((e) => boundNames(e, out));
68
- else if (id.type === "ObjectPattern") id.properties.forEach((p) => boundNames(p.type === "Property" ? p.value : p.argument, out));
69
- else if (id.type === "AssignmentPattern") boundNames(id.left, out);
70
- else if (id.type === "RestElement") boundNames(id.argument, out);
71
- };
72
- function withConditions(program, code, { locals, decls }) {
73
- if (!/\b(?:media|container|supports|attr|within)\b/.test(code)) return locals;
74
- const ctors = /* @__PURE__ */ new Set();
75
- for (const d of decls) for (const x of d.specifiers) if (x.type === "ImportSpecifier" && CONDITIONS.has(nameOf(x.imported))) ctors.add(x.local.name);
76
- const all = new Set(locals);
77
- const walk = (node) => {
78
- if (!Predicate.isObject(node) || typeof node.type !== "string") return;
79
- const n = node;
80
- if (n.type === "VariableDeclarator" && n.init?.type === "CallExpression") {
81
- const c = n.init.callee;
82
- if (c.type === "Identifier" && ctors.has(c.name) || c.type === "MemberExpression" && !c.computed && c.property.type === "Identifier" && CONDITIONS.has(c.property.name) && locals.has(rootIdent(c.object) ?? "")) boundNames(n.id, all);
83
- }
84
- for (const k in node) {
85
- const v = node[k];
86
- if (Array.isArray(v)) v.forEach(walk);
87
- else if (Predicate.isObject(v) && "type" in v) walk(v);
88
- }
89
- };
90
- walk(program);
91
- return all;
92
- }
93
- const declsOf = (stmts, out) => stmts.forEach((s) => {
94
- if (s.type === "VariableDeclaration") s.declarations.forEach((d) => boundNames(d.id, out));
95
- else if ((s.type === "FunctionDeclaration" || s.type === "ClassDeclaration") && s.id) out.add(s.id.name);
96
- });
97
- const declares = (n, out) => {
98
- if (n.type === "ArrowFunctionExpression" || n.type === "FunctionExpression" || n.type === "FunctionDeclaration") {
99
- n.params.forEach((p) => boundNames(p, out));
100
- if (n.type === "FunctionExpression" && n.id) out.add(n.id.name);
101
- } else if (n.type === "BlockStatement" || n.type === "StaticBlock") declsOf(n.body, out);
102
- else if (n.type === "SwitchCase") declsOf(n.consequent, out);
103
- else if (n.type === "ForStatement" && n.init) declsOf([n.init], out);
104
- else if (n.type === "ForInStatement" || n.type === "ForOfStatement") declsOf([n.left], out);
105
- else if (n.type === "CatchClause") boundNames(n.param, out);
106
- };
107
- function findSites(program, locals) {
108
- const sites = [];
109
- const scopes = [/* @__PURE__ */ new Set()];
110
- const walk = (node, inFn) => {
111
- if (!Predicate.isObject(node) || typeof node.type !== "string") return;
112
- const n = node;
113
- if ((n.type === "CallExpression" || n.type === "NewExpression") && locals.has(rootIdent(n.callee) ?? "")) {
114
- sites.push({
115
- start: n.start,
116
- end: n.end,
117
- inFn,
118
- locals: scopes[scopes.length - 1]
119
- });
120
- return;
121
- }
122
- const fn = inFn || /Function/.test(n.type);
123
- const own = /* @__PURE__ */ new Set();
124
- declares(n, own);
125
- scopes.push(own.size ? /* @__PURE__ */ new Set([...scopes[scopes.length - 1], ...own]) : scopes[scopes.length - 1]);
126
- for (const k in node) {
127
- const v = node[k];
128
- if (Array.isArray(v)) v.forEach((c) => walk(c, fn));
129
- else if (Predicate.isObject(v) && "type" in v) walk(v, fn);
130
- }
131
- scopes.pop();
132
- };
133
- walk(program, false);
134
- return sites;
135
- }
136
- const instrument = Effect.fn("cssints.instrument")(function* (code, id, client = true) {
137
- const { program } = parseSync(id, code);
138
- const imp = yield* findCssImport(program, code, id, client);
139
- if (!imp) return null;
140
- const sites = findSites(program, withConditions(program, code, imp));
141
- const ms = new MagicString(code);
142
- const hoisted = [];
143
- const file = Formatter.formatJson(id);
144
- sites.forEach((s, n) => {
145
- const site = `__site(__at(${file}, ${n}, ${s.start}), `;
146
- const expr = code.slice(s.start, s.end);
147
- if (s.inFn) {
148
- const names = new Set(expr.match(/[\p{L}\p{N}_$]+/gu));
149
- const dead = [...s.locals].filter((x) => names.has(x));
150
- hoisted.push(dead.length ? `{ ${site}${expr}); let ${dead.join(", ")}; }` : `${site}${expr});`);
151
- } else {
152
- ms.prependLeft(s.start, site).appendRight(s.end, ")");
153
- hoisted.push(`__unseen(${file}, ${n}) && ${site}${expr});`);
154
- }
155
- });
156
- imp.decls.forEach((d, i) => {
157
- if (d.source.value !== "cssints") return;
158
- const ns = d.specifiers.find((x) => x.type === "ImportNamespaceSpecifier");
159
- const named = d.specifiers.filter((x) => !isRuntime(d, x));
160
- const bind = ns ? ns.local.name : `{ ${named.map((x) => `${Formatter.formatJson(importedName(x))}: ${x.local.name}`).join(", ")} }`;
161
- ms.overwrite(d.start, d.end, `import { css as __css${i} } from ${Formatter.formatJson(RUNTIME)}; const ${bind} = __css${i};${keptImport(d, code)}`);
162
- });
163
- ms.prepend(`import { __at, __site, __unseen } from ${Formatter.formatJson(RUNTIME)};\n`);
164
- if (hoisted.length) ms.append(`\nexport function __cssints_hoisted() {\n${hoisted.join("\n")}\n}\n`);
165
- return {
166
- code: ms.toString(),
167
- sites,
168
- imp
169
- };
170
- });
171
- //#endregion
172
- export { keptImport as i, RUNTIME as n, instrument as r, CV_CALL as t };
@@ -1,9 +0,0 @@
1
- import "./node-CdhAGmF3.mjs";
2
- import { Effect } from "effect";
3
- //#region src/lib.d.ts
4
- /** What firstThatWorks() builds: its values as text, the wanted one first. */
5
- interface Fallback {
6
- __fallback: string[];
7
- }
8
- //#endregion
9
- export { Fallback as t };
@@ -1,5 +0,0 @@
1
- //#region src/runtime.d.ts
2
- type ClassValue = string | false | null | undefined | 0 | ClassValue[];
3
- declare const cx: (...a: ClassValue[]) => string;
4
- //#endregion
5
- export { cx as n, ClassValue as t };