diff --git a/src/BlazeServiceProvider.php b/src/BlazeServiceProvider.php index fa338c91..ced25445 100644 --- a/src/BlazeServiceProvider.php +++ b/src/BlazeServiceProvider.php @@ -4,10 +4,12 @@ use Livewire\Blaze\Compiler\Profiler; use Livewire\Blaze\Runtime\BlazeRuntime; +use Illuminate\Console\Events\CommandFinished; use Illuminate\Support\ServiceProvider; use Illuminate\Support\Facades\Blade; use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\View; +use Illuminate\View\Component; use Livewire\Blaze\Memoizer\Memo; class BlazeServiceProvider extends ServiceProvider @@ -47,6 +49,7 @@ public function boot(): void $this->registerBladeMacros(); $this->interceptBladeCompilation(); $this->registerDebuggerMiddleware(); + $this->registerViewClearListener(); $this->registerOctaneListener(); } @@ -167,6 +170,20 @@ protected function registerDebuggerMiddleware(): void }); } + /** + * Register a listener for the view:clear command to flush the compiled cache. + */ + protected function registerViewClearListener(): void + { + Event::listen(CommandFinished::class, function (CommandFinished $event) { + if ($event->command === 'view:clear') { + $this->app->make(BlazeRuntime::class)->flushCompiled(); + + Component::flushCache(); + } + }); + } + /** * Reset Blaze state between Octane requests. */ diff --git a/src/Runtime/BlazeRuntime.php b/src/Runtime/BlazeRuntime.php index 276d8cd8..1c960e26 100644 --- a/src/Runtime/BlazeRuntime.php +++ b/src/Runtime/BlazeRuntime.php @@ -233,11 +233,6 @@ public function processPassthroughContent(string $method, string $content): stri return $content; } - private function getCompiledPath(): string - { - return $this->compiledPath ??= config('view.compiled'); - } - /** * Set the application instance (used by Octane to swap in the sandbox). */ @@ -258,6 +253,14 @@ public function flushState(): void $this->slotsStack = []; } + /** + * Clear the in-memory compilation cache. + */ + public function flushCompiled(): void + { + $this->compiled = []; + } + /** * Lazy-load properties whose canonical values are set after BlazeRuntime is constructed * ($errors by middleware, compiledPath by parallel testing infrastructure). @@ -270,4 +273,12 @@ public function __get(string $name): mixed default => throw new \InvalidArgumentException("Property {$name} does not exist"), }; } + + /** + * Get the compiled path. + */ + private function getCompiledPath(): string + { + return $this->compiledPath ??= config('view.compiled'); + } } diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php index e85c18b9..d8b291f6 100644 --- a/tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -2,10 +2,13 @@ use Illuminate\Container\Container; use Illuminate\Contracts\View\Engine; +use Illuminate\Foundation\Testing\WithConsoleEvents; use Illuminate\Support\Facades\Artisan; use Livewire\Blaze\Blaze; use Livewire\Blaze\BlazeManager; +uses(WithConsoleEvents::class); + beforeEach(fn () => Artisan::call('view:clear')); test('renders components', function () { @@ -14,13 +17,21 @@ test('renders components with blaze off', function () { Blaze::disable(); - + view('mix')->render(); })->throwsNoExceptions(); test('renders components with blaze off and debug mode on', function () { Blaze::disable(); Blaze::debug(); + + view('mix')->render(); +})->throwsNoExceptions(); + +test('renders components after clearing views', function () { + view('mix')->render(); + + Artisan::call('view:clear'); view('mix')->render(); })->throwsNoExceptions();