getCacheKey($className); $cacheItem = $this->cache->get($cacheKey); // Check cache hit (CacheResult has $isHit property, not isHit() method) if ($cacheItem !== null && $cacheItem->isHit) { $metadata = CompiledComponentMetadata::fromArray($cacheItem->value); // Check staleness if (! $this->isStale($metadata, $className)) { return $metadata; } // Stale - recompile } // Cache miss or stale - compile and cache return $this->compileAndCache($className); } /** * Get metadata for multiple components (batch operation) * * @param array $classNames * @return array */ public function getBatch(array $classNames): array { $metadata = []; $toCompile = []; // Try cache first foreach ($classNames as $className) { $cacheKey = $this->getCacheKey($className); $cacheItem = $this->cache->get($cacheKey); if ($cacheItem !== null && $cacheItem->isHit) { $meta = CompiledComponentMetadata::fromArray($cacheItem->value); if (! $this->isStale($meta, $className)) { $metadata[$className] = $meta; continue; } } $toCompile[] = $className; } // Compile missing/stale if (! empty($toCompile)) { $compiled = $this->compiler->compileBatch($toCompile); // Cache batch $this->cacheBatch($compiled); $metadata = array_merge($metadata, $compiled); } return $metadata; } /** * Check if component metadata exists in cache */ public function has(string $className): bool { $cacheKey = $this->getCacheKey($className); return $this->cache->has($cacheKey); } /** * Invalidate cached metadata for component */ public function invalidate(string $className): bool { $cacheKey = $this->getCacheKey($className); return $this->cache->forget($cacheKey); } /** * Clear all cached metadata */ public function clear(): bool { // This would require wildcard deletion: livecomponent:metadata:* return true; } /** * Warm cache for multiple components * * Pre-compiles and caches metadata for performance-critical components. * * @param array $classNames */ public function warmCache(array $classNames): int { $compiled = $this->compiler->compileBatch($classNames); $this->cacheBatch($compiled); return count($compiled); } /** * Get cache statistics */ public function getStats(): array { return [ 'cache_type' => 'component_metadata', 'default_ttl_hours' => self::DEFAULT_TTL_HOURS, ]; } /** * Compile and cache component metadata */ private function compileAndCache(string $className): CompiledComponentMetadata { $metadata = $this->compiler->compile($className); $cacheKey = $this->getCacheKey($className); $cacheItem = CacheItem::forSet( key: $cacheKey, value: $metadata->toArray(), ttl: Duration::fromHours(self::DEFAULT_TTL_HOURS) ); $this->cache->set($cacheItem); return $metadata; } /** * Cache batch of compiled metadata * * @param array $metadata */ private function cacheBatch(array $metadata): void { $cacheItems = []; foreach ($metadata as $className => $meta) { $cacheKey = $this->getCacheKey($className); $cacheItems[] = CacheItem::forSet( key: $cacheKey, value: $meta->toArray(), ttl: Duration::fromHours(self::DEFAULT_TTL_HOURS) ); } if (! empty($cacheItems)) { $this->cache->set(...$cacheItems); } } /** * Check if metadata is stale */ private function isStale(CompiledComponentMetadata $metadata, string $className): bool { try { $reflection = new \ReflectionClass($className); $classFile = $reflection->getFileName(); if ($classFile === false) { return false; } return $metadata->isStale($classFile); } catch (\ReflectionException $e) { return true; } } /** * Get cache key for component class */ private function getCacheKey(string $className): CacheKey { return CacheKey::fromString(self::CACHE_PREFIX . $className); } }