> ## Documentation Index
> Fetch the complete documentation index at: https://docs.westyx.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Vue SDK - Caching behaviour

> How the Vue SDK caches, when it refreshes, and what it does when the server pushes back.

## What the client holds

One bulk `GET /v1/sync` returns every config and flag the key can see, and the
client keeps that snapshot in memory. Reads are served from it - they never touch
the network and never block.

## When it refreshes

| Trigger                          | What happens                                                    |
| -------------------------------- | --------------------------------------------------------------- |
| A live-stream event              | An immediate refresh                                            |
| A read after the TTL has elapsed | A background refresh; the caller is served the current snapshot |
| An explicit sync                 | A refresh, awaited by the caller                                |

While the live stream is connected the effective TTL is at least 60 seconds:
updates already arrive by push, so polling on top of it would be redundant.

## A read never waits

A read past the TTL starts a refresh and returns the snapshot it already has.
This is deliberate: a component rendering a flag should not be blocked on a
network round trip, and a value a few seconds old is almost always the right
answer. The refresh replaces the snapshot when it lands, and everything bound to
it updates.

## Concurrent refreshes are one request

An event burst, a TTL expiry and an explicit sync arriving together produce a
**single** request. Every caller shares it, and a response is applied only if no
newer one has already been applied - so a slow reply cannot overwrite fresher
data.

## ETag

Each snapshot carries the server's `ETag`, sent back as `If-None-Match`. When
nothing has changed the server answers `304 Not Modified` and no data is
transferred. A 304 is a **successful** sync: it renews the TTL and clears any
degraded state, exactly as a 200 does.

## Large numbers

An integer a double cannot represent exactly - above 2^53 - is decoded as a
`bigint` rather than silently rounded. Order ids, amounts in minor units and
nanosecond timestamps survive intact. Every value a double holds exactly stays a
`number`, so arithmetic on ordinary config values is unchanged.

```ts theme={null}
// The server sent 9007199254740993.
const id = client.getConfig('order.next_id'); // 9007199254740993n
```

## When the server pushes back

| Response                 | Behaviour                                                                                                                                                                       |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `402 Payment Required`   | Reads keep being served from the snapshot. Refresh slows to one attempt every five minutes rather than stopping, so the client recovers on its own once the invoice is settled. |
| `429` with `Retry-After` | Honoured, clamped to 5-300 seconds.                                                                                                                                             |
| `429` quarantine         | Syncing is suspended until the quarantine expires.                                                                                                                              |
| `5xx`                    | Retried on a jittered exponential schedule, 1 s to 30 s.                                                                                                                        |
| A body over 8 MiB        | Rejected with `NexusResponseTooLargeError` rather than parsed as a truncated document.                                                                                          |

Throughout all of these, reads keep returning the last good snapshot.

## Releasing the client

Tearing down the client releases the stream, every timer and every listener, and
is final - a refresh already in flight cannot re-arm anything afterwards. The
framework integration does this for you when the component tree or application is
destroyed.
