# Gotchas

## `invalidate([])` is a no-op

An empty prefix matches nothing. Use `cache.clear()` to wipe everything.

<Aside type="caution" title="No effect">

```ts
// This does nothing: an empty prefix matches no key
cache.invalidate([])
```

</Aside>

```ts title="Correct"
// Use clear() to wipe the entire cache
cache.clear()
```

## `invalidate()` is prefix-based, not exact-match

A prefix matches every key that starts with it, including nested sub-keys.

```ts
// invalidate(['order', 'details', '42']) also matches:
//   ['order', 'details', '42']
//   ['order', 'details', '42', 'comments']
//   ['order', 'details', '42', 'attachments']
//
// It does NOT match:
//   ['order', 'details', '43']
//   ['order', 'list']
```

## `ref.set()` and `ref.update()` write to the cache

They update both the Angular resource and the `DataCache`. Optimistic values
survive cache version bumps from unrelated invalidations. Call `invalidate()`
to trigger a fresh server fetch.

```ts
// set() and update() write to both the Angular resource AND the DataCache.
// Optimistic values survive cache version bumps from unrelated invalidations.
ref.set(newValue)
ref.update(prev => ({ ...prev, name: 'updated' }))

// To trigger a fresh server fetch after an optimistic update:
cache.invalidate(['order', 'details', '42'])
```

## Cache keys are untyped at the boundary

`DataCache` stores `unknown` internally. Type correctness depends on consistent
key-to-type pairings in your code.

```ts
// Nothing prevents this: both compile fine
cache.set(['user', '1'], { name: 'Alice' })       // User
const entry = cache.get<Order[]>(['user', '1'])  // reads as Order[]

// Convention: one key prefix per type, enforced in your API service
```
