strata-css
Advanced tools
+10
-0
@@ -5,2 +5,12 @@ # Changelog | ||
| ## [1.5.12] — 2026-08-03 | ||
| ### Fixed | ||
| - **`ml-` / `mr-` / `pl-` / `pr-` silently produced no CSS.** The spacing arbitrary-value regex accepts the suffix set `[trblxyes]` — the union of physical naming (`t r b l`, as used by Tailwind and Bootstrap 4) and logical-style naming (`x y e s`, as used by Bootstrap 5) — but `SPACING_PROPS` defined only the latter plus `t`/`b`. A matched-but-undefined suffix made the pattern function return `null`, so `pl-[10px]`, `ml-3`, `pr-sm-[1rem]` and friends compiled cleanly and emitted nothing: no CSS, no warning, no way for a consumer to notice. This affected 24 arbitrary shapes (4 prefixes × unconditional + 5 breakpoints) plus every named and breakpoint-named variant of the same four prefixes. `ml`/`mr`/`pl`/`pr` are now plain aliases of `ms`/`me`/`ps`/`pe` — which are themselves physical (`left`/`right`), so the spellings are exactly equivalent and no RTL behaviour differs. Purely additive; existing spellings unchanged. | ||
| ### Tests | ||
| - Regression coverage for the above in `test/verify.js`, including a guard asserting that **every** suffix the arbitrary regex accepts resolves — so adding a suffix to the char class without a matching `SPACING_PROPS` entry now fails the suite instead of shipping another silent no-op. | ||
| --- | ||
| ## [1.5.11] — 2026-07-27 | ||
@@ -7,0 +17,0 @@ |
+1
-1
| { | ||
| "name": "strata-css", | ||
| "version": "1.5.11", | ||
| "version": "1.5.12", | ||
| "_versioningNote": "Stable: 1.0.0 / 1.1.0 / 2.0.0 | Beta: 1.1.0-beta.1 / 1.1.0-beta.2", | ||
@@ -5,0 +5,0 @@ "description": "A modern CSS framework combining Bootstrap components with Tailwind JIT processing", |
+41
-6
@@ -16,4 +16,5 @@ /** | ||
| // ─── State ──────────────────────────────────────────────────────────── | ||
| let dirty = true | ||
| let cachedCSS = null // final output CSS string from last cold build | ||
| let dirty = true | ||
| let cachedCSS = null // final output CSS string from last cold build | ||
| let cachedBuildInput = null // resolved inputCSSPath the cache above was built from | ||
@@ -81,3 +82,3 @@ // ─── Config cache ───────────────────────────────────────────────────── | ||
| const { scanFiles } = require('./scanner/scanner') | ||
| const { scanFiles, getWatchFiles } = require('./scanner/scanner') | ||
| const { generate } = require('./generator/generator') | ||
@@ -92,2 +93,30 @@ | ||
| // Tell the caller's bundler (webpack/Turbopack/esbuild/etc.) that this | ||
| // output depends on every scanned content file, not just the CSS file | ||
| // being processed — otherwise an unchanged CSS file + unchanged config | ||
| // reads as "nothing changed" and a stale cached build gets served even | ||
| // when a .tsx file added/changed a utility class. | ||
| const watchFiles = getWatchFiles(contentGlobs) | ||
| for (let i = 0; i < watchFiles.length; i++) { | ||
| result.messages.push({ | ||
| type: 'dependency', | ||
| plugin: 'strata-css', | ||
| file: path.resolve(cwd, watchFiles[i]), | ||
| parent: from, | ||
| }) | ||
| } | ||
| const configPath = path.resolve(cwd, 'strata.config.js') | ||
| const configPathCjs = path.resolve(cwd, 'strata.config.cjs') | ||
| const resolvedConfigPath = fs.existsSync(configPathCjs) ? configPathCjs | ||
| : fs.existsSync(configPath) ? configPath | ||
| : null | ||
| if (resolvedConfigPath) { | ||
| result.messages.push({ | ||
| type: 'dependency', | ||
| plugin: 'strata-css', | ||
| file: resolvedConfigPath, | ||
| parent: from, | ||
| }) | ||
| } | ||
| // Replace @strata directives | ||
@@ -118,4 +147,9 @@ let baseInserted = false | ||
| module.exports.build = async (inputCSSPath, outputCSSPath, opts = {}) => { | ||
| const resolvedInput = path.resolve(inputCSSPath) | ||
| // ── Warm path: return cached CSS, no work at all ────────────────── | ||
| if (!dirty && cachedCSS) { | ||
| // Only valid if the cache was built from this same input file — the | ||
| // module-level cache is shared across calls, so a different inputCSSPath | ||
| // must never be served the previous input's stale compiled output. | ||
| if (!dirty && cachedCSS && cachedBuildInput === resolvedInput) { | ||
| if (outputCSSPath) fs.writeFileSync(outputCSSPath, cachedCSS) | ||
@@ -153,4 +187,5 @@ return cachedCSS | ||
| cachedCSS = css | ||
| dirty = false | ||
| cachedCSS = css | ||
| cachedBuildInput = resolvedInput | ||
| dirty = false | ||
@@ -157,0 +192,0 @@ if (outputCSSPath) { |
Sorry, the diff of this file is too big to display
301532
1.25%5749
0.79%