rainbowindex 0.3.0 → 0.4.1
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.
- package/CHANGELOG.md +135 -0
- package/README.md +27 -4
- package/dist/browser.d.ts +2 -2
- package/dist/browser.mjs +1 -1
- package/dist/chunk-3HRMFZGE.mjs +19 -0
- package/dist/{chunk-AZXWJ625.mjs → chunk-53WD6U2X.mjs} +826 -610
- package/dist/{chunk-IE6N76PW.mjs → chunk-6GTG5SZJ.mjs} +5269 -4660
- package/dist/{chunk-AUWGHSTO.mjs → chunk-IYIUS7AE.mjs} +64 -126
- package/dist/{chunk-SOMDX7V6.mjs → chunk-KRZL4IDK.mjs} +337 -421
- package/dist/chunk-WYMCN5OC.mjs +244 -0
- package/dist/cli.mjs +280 -277
- package/dist/{index-CfDtWufj.d.ts → context-ruu2x_jR.d.ts} +15 -70
- package/dist/editor.d.ts +98 -28
- package/dist/editor.mjs +37 -8
- package/dist/{index-DK6APAGD.d.ts → index-Dp6i5TSv.d.ts} +16 -12
- package/dist/index.d.ts +4 -4
- package/dist/index.mjs +4 -4
- package/dist/safelist-D9-Plqta.d.ts +109 -0
- package/dist/vite.mjs +80 -83
- package/package.json +2 -1
- package/dist/chunk-RHOQSN2B.mjs +0 -691
- package/dist/safelist-CH3_PywB.d.ts +0 -43
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,141 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.4.1] - 2026-08-25
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Automatic zero-CLS font fallbacks.** Any `@font` slot whose family is in
|
|
13
|
+
the built-in metrics table (~100 common Google + system families, generated
|
|
14
|
+
from `@capsizecss/metrics` at development time — no new runtime dependency)
|
|
15
|
+
now gets a metrics-adjusted local fallback `@font-face` automatically. The
|
|
16
|
+
fallback font is picked from the slot's stack, or by the web font's
|
|
17
|
+
category (Arial / Times New Roman / Courier New). Opt out with
|
|
18
|
+
`metrics: none;`, pick the matched local font with `metrics: "Segoe UI";`,
|
|
19
|
+
or keep full manual control with
|
|
20
|
+
`metrics: "Arial" <size-adjust> <ascent> <descent> <line-gap>;`.
|
|
21
|
+
- **`face:` entries** — local font files are now declared as repeatable
|
|
22
|
+
`face: <src> [{ overrides }]` entries, one grammar for every face:
|
|
23
|
+
`display: "Satoshi" { face: /Satoshi.woff2; face: /Satoshi-Italic.woff2 { style: italic; } }`.
|
|
24
|
+
- **Fallback stacks work with `from google`** —
|
|
25
|
+
`sans: "Inter", ui-sans-serif, sans-serif from google;` now parses as a
|
|
26
|
+
google slot with fallbacks (previously it silently became a manual stack).
|
|
27
|
+
- **@font now warns instead of ignoring silently**: unknown option keys
|
|
28
|
+
(RI-1217), `preload` on non-local slots where it can have no effect
|
|
29
|
+
(RI-1219), and partial or invalid `metrics` values (RI-1220).
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- The `@font` parser was rebuilt on the shared entry scanner: one pass, no
|
|
34
|
+
regex preambles, no re-serialization. Public API (`parseFontBody`,
|
|
35
|
+
`parseNestedFontBlock`) is unchanged.
|
|
36
|
+
- **Incremental rebuilds only re-do changed work** — the scanner keeps a
|
|
37
|
+
per-file cache keyed on mtime + size, so a CLI watch or Vite HMR rebuild
|
|
38
|
+
re-reads and re-extracts only the files that actually changed instead of
|
|
39
|
+
the whole project. The CSS entry analysis is memoized on the entry text
|
|
40
|
+
(stable theme identity across rebuilds), Google-font resolution keeps its
|
|
41
|
+
identity when metadata is unchanged, and per-class compilation results
|
|
42
|
+
(rule, warnings, token usage) are replayed across rebuilds from a
|
|
43
|
+
theme-keyed cache. A one-file edit in a large project now costs
|
|
44
|
+
O(changed files) instead of O(project).
|
|
45
|
+
- **`ri()` conditional args hit the cache fast path** — falsy arguments
|
|
46
|
+
(`ri("flex", isActive && "bg-blue-500")`) no longer force re-tokenization
|
|
47
|
+
on every call: the raw-key cache skips falsy primitives, making cached
|
|
48
|
+
conditional-pattern calls ~4x faster.
|
|
49
|
+
- **Cheaper compile passes** — duplicate class names across `@apply` rules
|
|
50
|
+
resolve once per pass, the `@slot`/`@apply` walks no longer traverse the
|
|
51
|
+
generated utility CSS, custom `@utility` bodies parse once per body text
|
|
52
|
+
instead of once per variant form, and the editor candidate collector's
|
|
53
|
+
context assignment went from quadratic to a sorted sweep. As part of the
|
|
54
|
+
compile-result replay, engine-level compilation warnings are now
|
|
55
|
+
deduplicated (final project output already was).
|
|
56
|
+
- **Internal restructuring (behavior-preserving)** — the directive body
|
|
57
|
+
parsers were split by grammar family: `@color` and `@font` now own their
|
|
58
|
+
own modules, and the generic key-value/entry grammars sit together in the
|
|
59
|
+
directives foundation. The `parsers` import surface is unchanged.
|
|
60
|
+
|
|
61
|
+
### Deprecated
|
|
62
|
+
|
|
63
|
+
- The older `@font` forms still parse and desugar into the new model, but
|
|
64
|
+
warn (RI-1218) and will be removed in a future release: `@face { src: …; }`
|
|
65
|
+
blocks and the `italic:` shorthand (use `face:`), `from "<path>"` (use
|
|
66
|
+
`face:`), `from system` (use bare `system`), the `fallback:` key (list
|
|
67
|
+
fallbacks in the slot preamble), the five-key metrics cluster
|
|
68
|
+
`metricsFallback`/`sizeAdjust`/`ascent`/`descent`/`lineGap` (use
|
|
69
|
+
`metrics:`), and the `unicodeRange` spelling (use `unicode-range`).
|
|
70
|
+
|
|
71
|
+
### Removed
|
|
72
|
+
|
|
73
|
+
- **`@font` `subset:`** — the Google css2 API takes no subset hint, so the
|
|
74
|
+
key never affected the emitted URL. It now warns (RI-1218) and is ignored.
|
|
75
|
+
- **`FontSlot` / `FontFace` fields** — the five slot-level metrics fields
|
|
76
|
+
(`metricsFallback`, `sizeAdjust`, `ascent`, `descent`, `lineGap`) are
|
|
77
|
+
replaced by a single `metrics?: FontMetricsConfig | null`; slot-level
|
|
78
|
+
`preload` moved onto the faces; `FontFace.subset` is gone. Stylesheets are
|
|
79
|
+
unaffected — this only touches code importing those types directly.
|
|
80
|
+
|
|
81
|
+
### Fixed
|
|
82
|
+
|
|
83
|
+
- **`ri()` stroke-width vs stroke-color conflict — for real this time.** The
|
|
84
|
+
v0.4.0 changelog described this fix, but the implementation did not ship in
|
|
85
|
+
that release: `ri("stroke-2 stroke-red-500")` still dropped `stroke-2`. The
|
|
86
|
+
`stroke` prefix is now actually width-vs-color dual-mode (mirroring
|
|
87
|
+
`border`/`outline`): decimal and non-color arbitrary values claim
|
|
88
|
+
`stroke-width`, color values claim `stroke`. Same-property conflicts
|
|
89
|
+
(`stroke-2` vs `stroke-4`, `stroke-red-500` vs `stroke-blue-500`) still
|
|
90
|
+
merge as before. The emission↔claim parity suite no longer carries a
|
|
91
|
+
stroke exception, and regression tests pin the merged output.
|
|
92
|
+
- **Directive rewriter no longer duplicates unclosed blocks** — an
|
|
93
|
+
unterminated `{` inside a `@color` body made the Vite-plugin pre-pass
|
|
94
|
+
re-emit the text before it (`@color { accent: 0.18 330 { inline` came out
|
|
95
|
+
with the entry doubled). The rewriter's two hand-rolled brace walks were
|
|
96
|
+
replaced by one shared walker built on the same brace matcher the directive
|
|
97
|
+
scan already uses, which also makes quotes and comments inside blocks
|
|
98
|
+
behave consistently across the rewrite passes.
|
|
99
|
+
|
|
100
|
+
## [0.4.0] - 2026-08-20
|
|
101
|
+
|
|
102
|
+
### Added
|
|
103
|
+
|
|
104
|
+
- **GitHub Packages publishing** — every release is now also published to
|
|
105
|
+
GitHub Packages as `@rainbowindex/rainbowindex` (that registry requires an
|
|
106
|
+
owner-scoped name). The README documents installing it under the usual
|
|
107
|
+
name via `pnpm add rainbowindex@npm:@rainbowindex/rainbowindex`, so all
|
|
108
|
+
documented imports and CLI invocations work unchanged.
|
|
109
|
+
|
|
110
|
+
### Changed
|
|
111
|
+
|
|
112
|
+
- **Stricter CLI argument validation** — the CLI is now driven by a
|
|
113
|
+
declarative command table that knows which flags and positionals each
|
|
114
|
+
command accepts. Flags used under the wrong command, stray positional
|
|
115
|
+
arguments, and flags missing their value are rejected with an error
|
|
116
|
+
instead of being silently ignored.
|
|
117
|
+
- **Internal restructuring** (behavior-preserving, net ≈ −4,500 lines) —
|
|
118
|
+
the merge, scanner, and effects modules were split into focused modules;
|
|
119
|
+
the spacing/border prefix→property maps are now single-sourced from the
|
|
120
|
+
merge conflict table with a machine-checked parity test; `@apply` reuses
|
|
121
|
+
the engine's cascade ordering; the CLI and PostCSS builds share one
|
|
122
|
+
orchestration path with parallelized font fetches; and all internal
|
|
123
|
+
import cycles were broken. Public entry points are unchanged.
|
|
124
|
+
|
|
125
|
+
### Fixed
|
|
126
|
+
|
|
127
|
+
- **`ri()` stroke-width vs stroke-color conflict** — width-shaped `stroke-*`
|
|
128
|
+
classes (`stroke-2`, `stroke-1.5`, `stroke-[3px]`) were claiming the
|
|
129
|
+
`stroke` color property in the merge conflict table, so
|
|
130
|
+
`ri("stroke-2 stroke-red-500")` dropped `stroke-2` even though the two
|
|
131
|
+
classes set different CSS properties. The `stroke` prefix is now
|
|
132
|
+
width-vs-color dual-mode (mirroring `border`/`outline`): decimal and
|
|
133
|
+
non-color arbitrary values claim `stroke-width`, color values claim
|
|
134
|
+
`stroke`. Same-property conflicts (`stroke-2` vs `stroke-4`,
|
|
135
|
+
`stroke-red-500` vs `stroke-blue-500`) still merge as before.
|
|
136
|
+
- **Watch mode double rebuild** — debouncing and rate-limiting now share a
|
|
137
|
+
single timer, so a burst of file changes landing inside the rate-limit
|
|
138
|
+
window schedules one rebuild instead of a redundant second one.
|
|
139
|
+
- **`@color` entries without a colon** — a colon-less fragment in an
|
|
140
|
+
`@color` block now produces a warning and is skipped on its own; it no
|
|
141
|
+
longer swallowed the entry that followed it.
|
|
142
|
+
|
|
8
143
|
## [0.3.0] - 2026-08-14
|
|
9
144
|
|
|
10
145
|
### Added — editor tooling API (phase 2)
|
package/README.md
CHANGED
|
@@ -28,6 +28,28 @@ pnpm add rainbowindex
|
|
|
28
28
|
|
|
29
29
|
Requires Node `>=20.19`. The package is **ESM-only** — there is no CommonJS build, so `require("rainbowindex")` is only supported on runtimes that can `require()` ES modules (Node 20.19+); use `import` otherwise (e.g. an ESM `postcss.config.js`/`.mjs`). `postcss` is a required peer dependency, `vite` an optional one; `lightningcss`, `chokidar`, and `tinyglobby` are bundled as direct deps.
|
|
30
30
|
|
|
31
|
+
### From GitHub Packages
|
|
32
|
+
|
|
33
|
+
Every release is also published to [GitHub Packages](https://github.com/rainbowindex/rainbowindex/pkgs/npm/rainbowindex) as `@rainbowindex/rainbowindex` — the same build under an owner-scoped name, which that registry requires. Point the scope at the registry in your project's `.npmrc`:
|
|
34
|
+
|
|
35
|
+
```ini
|
|
36
|
+
@rainbowindex:registry=https://npm.pkg.github.com
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
GitHub Packages authenticates every read, including public ones, so put a [personal access token (classic)](https://github.com/settings/tokens) with the `read:packages` scope in your `~/.npmrc`:
|
|
40
|
+
|
|
41
|
+
```ini
|
|
42
|
+
//npm.pkg.github.com/:_authToken=YOUR_TOKEN
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Then install under the alias `rainbowindex`, so every import, `@import`, and CLI invocation in the docs below works unchanged:
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
pnpm add rainbowindex@npm:@rainbowindex/rainbowindex
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Without the alias — `pnpm add @rainbowindex/rainbowindex` — the package resolves under its scoped name, and specifiers become `@rainbowindex/rainbowindex`, `@rainbowindex/rainbowindex/vite`, and so on.
|
|
52
|
+
|
|
31
53
|
## Quick start (Vite)
|
|
32
54
|
|
|
33
55
|
The fastest path is the Vite plugin, which auto-injects PostCSS config and discovers your CSS entry on first dev-server listen.
|
|
@@ -189,7 +211,7 @@ Customization happens in your CSS input, not a JS config. The engine recognizes:
|
|
|
189
211
|
| `@color` | Define color tokens. Supports generative (`chroma hue`), explicit (`oklch(...)`, `#rrggbb`), light/dark pairs, and aliases. |
|
|
190
212
|
| `@spacing` | Set the spacing base unit. |
|
|
191
213
|
| `@text` | Define text size tokens (`size, line-height`). |
|
|
192
|
-
| `@font`, `@font-face` | Register font families inside a single `@font { … }` block.
|
|
214
|
+
| `@font`, `@font-face` | Register font families inside a single `@font { … }` block. Local files are repeatable `face:` entries (e.g. upright + italic). Known families get an automatic zero-CLS metrics fallback (`metrics: none` opts out). |
|
|
193
215
|
| `@rounded` | Border-radius tokens; modifier sets corner shape (`round`, `squircle`, `superellipse(N)`, etc). |
|
|
194
216
|
| `@fluid` | Configure fluid type/spacing range. |
|
|
195
217
|
| `@animate` | Register named animations with inline `@keyframes`. |
|
|
@@ -220,10 +242,11 @@ Example:
|
|
|
220
242
|
}
|
|
221
243
|
|
|
222
244
|
@font {
|
|
223
|
-
sans: "Inter" from google { weight: 400 700; }
|
|
224
|
-
display: "Satoshi"
|
|
245
|
+
sans: "Inter", ui-sans-serif, sans-serif from google { weight: 400 700; }
|
|
246
|
+
display: "Satoshi" {
|
|
225
247
|
weight: 300 900;
|
|
226
|
-
|
|
248
|
+
face: /fonts/Satoshi.woff2;
|
|
249
|
+
face: /fonts/Satoshi-Italic.woff2 { style: italic; }
|
|
227
250
|
}
|
|
228
251
|
}
|
|
229
252
|
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { C as ColorDefinition, a as CompilationContext, b as CompilationSnapshot,
|
|
2
|
-
export { s as safelist } from './safelist-
|
|
1
|
+
export { C as ColorDefinition, a as CompilationContext, b as CompilationSnapshot, F as FluidConfig, T as TextSize, c as Theme, d as createCompilationContext, e as defaultTheme, f as finalizeCompilationContext, r as registerColorNames, g as registerCustomFontFamilies, h as registerCustomTextSizes, i as registerCustomUtility } from './context-ruu2x_jR.js';
|
|
2
|
+
export { D as DEFAULT_TEXT_SIZES, c as createRi, r as ri, s as safelist } from './safelist-D9-Plqta.js';
|
|
3
3
|
|
|
4
4
|
declare function browserEntryUnavailable(): never;
|
|
5
5
|
|
package/dist/browser.mjs
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// src/scanner/source-files.ts
|
|
2
|
+
var SOURCE_FILE_EXTENSIONS = Object.freeze([
|
|
3
|
+
"html",
|
|
4
|
+
"js",
|
|
5
|
+
"jsx",
|
|
6
|
+
"ts",
|
|
7
|
+
"tsx",
|
|
8
|
+
"md",
|
|
9
|
+
"mdx",
|
|
10
|
+
"vue",
|
|
11
|
+
"svelte"
|
|
12
|
+
]);
|
|
13
|
+
function isSourceFile(file) {
|
|
14
|
+
return SOURCE_FILE_EXTENSIONS.some((ext) => file.endsWith(`.${ext}`));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export {
|
|
18
|
+
isSourceFile
|
|
19
|
+
};
|