Add Stylesheets::resolvedFiles() for the design guard to reuse

Plan step 41 (ii): the design guard needs the set of files an application's
CSS entry pulls in, transitively, to check whether a package tag's
stylesheet is among them — reusing bundle()'s own import resolution and
cache rather than re-implementing @import parsing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
Andreas Reinhold / reini
2026-09-15 07:51:07 +02:00
co-authored by Claude Sonnet 5
parent e1fe573182
commit 7ec6960731
2 changed files with 34 additions and 0 deletions
+23
View File
@@ -92,6 +92,29 @@ final class Stylesheets
self::$cache = [];
}
/**
* Every file `$files` reaches, transitively, through the same `@import` resolution `bundle()`
* walks — real paths, `$files` themselves included — without concatenating anything.
* `DesignGuard::missingStylesheets()` (plan step 41) asks this: whether an application's CSS
* entry's import graph already reaches a given package stylesheet, which needs the file
* identities `bundle()` resolves, not the CSS it produces. Shares `bundle()`'s cache (and so
* its freshness rule) under the same key, `$base` fixed to `null`, since only `bundle()` ever
* populates it.
*
* @param list<string> $files
* @return list<string>
*/
public static function resolvedFiles(array $files): array
{
if ($files === []) {
return [];
}
self::bundle($files);
return array_keys(self::$cache[serialize([$files, null])]['files']);
}
/**
* @param array<string, int|false> $files every file a cached bundle inlined, with its mtime then
*/
+11
View File
@@ -82,6 +82,17 @@ it('bundles all.css with every import resolved, foundation first, every componen
->and($foundationPosition)->toBeLessThan($earliestOtherPosition);
});
it('resolves the files an entry imports, transitively, without bundling any content', function () {
$files = Stylesheets::resolvedFiles([stylesheetsBundlePath('components/split-button.css')]);
expect($files)->toContain(
stylesheetsBundlePath('components/split-button.css'),
stylesheetsBundlePath('components/button.css'),
stylesheetsBundlePath('components/menu.css'),
stylesheetsBundlePath('components/icon.css'),
);
});
it('keeps a file two others import once, at its first position', function () {
$dir = sys_get_temp_dir().'/livewire-material-bundle-'.Str::random(8);
File::makeDirectory($dir);