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;
}