array, 'html' => string]` value shape, and * the prefix-wildcard invalidation hook used by §14. */ interface RenderCache { /** * Read the rendered entry stored under `$key`. * * Returns null on miss, on expiry, or when the implementation * has had its layer flushed since the entry was written. * * On hit, the returned array carries exactly two keys: * * - `view_model` — the associative array snapshot of the * view model handed to the template engine on the write * that produced this entry. * - `html` — the rendered HTML string that the template * engine produced from that view model. * * @param string $key Cache key, typically produced by * {@see CacheKeyFactory::renderEmbedKey()} or * {@see CacheKeyFactory::renderAdhocKey()}. * * @return array{view_model: array, html: string}|null * Cached entry, or null on miss / expired. */ public function get( string $key ): ?array; /** * Write the rendered entry under `$key` with the given TTL * in seconds. * * Implementations MUST reject `$ttlSeconds <= 0` with * {@see \InvalidArgumentException}; a non-positive TTL has no * meaningful semantics for this layer. * * @param string $key Cache key. * @param array $viewModel View model snapshot. * @param string $html Rendered HTML. * @param int $ttlSeconds TTL in seconds; must be > 0. * * @throws InvalidArgumentException When `$ttlSeconds` is non-positive. */ public function put( string $key, array $viewModel, string $html, int $ttlSeconds ): void; /** * Remove the entry stored under `$key`. * * Idempotent: a call against an unknown key is a no-op. * * @param string $key Cache key. */ public function forget( string $key ): void; /** * Drop every entry stored in this cache layer. * * Scope is the layer instance, not the underlying store; if * an implementation shares storage with another layer, the * shared backend MUST still partition entries so flushing * one layer does not also drop a sibling layer's entries. */ public function flush(): void; /** * Drop every entry whose key begins with `$prefix`, returning * the count of removed entries. * * Used by the §14 `CacheInvalidator` to perform targeted * wildcard invalidation (for example, dropping every render * entry under a per-product prefix when that product's * snapshot changes) without flushing the entire layer. * * Behavior on an empty `$prefix` is implementation-defined; * implementations are encouraged to reject it as a defensive * guard against accidental layer-wide flushes. * * @param string $prefix Cache-key prefix. * * @return int Count of removed entries (>= 0). */ public function forgetByPrefix( string $prefix ): int; }