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

# Cache, storage, and signals

> Reference for the Layers SDK client cache, storage adapters for persistence, reactive signal primitives, singleton access, and other technical SDK details.

## Cache and storage

The client exposes a reactive cache:

```typescript theme={null}
const { cache } = client

cache.get('cache-key') // CacheEntry<QueryResult> | null
cache.invalidate('browse') // invalidate keys containing 'browse'
cache.persist() // save to storage
cache.restore() // restore from storage
cache.clear() // clear all
cache.stats.entries // current entry count
```

### Cache interface

```typescript theme={null}
interface Cache {
  get(key: string): CacheEntry<CacheValue> | null
  set(key: string, result: CacheValue): void
  isExpired(key: string): boolean
  invalidate(pattern: string): void
  persist(): void
  restore(): void
  clear(): void
  readonly stats: { entries: number }
}

interface CacheEntry<T> {
  data: T
  timestamp: number
  createdAt: number
}
```

`invalidate(pattern)` removes all cache entries whose key contains the given string. For example, `cache.invalidate('browse')` clears all collection browse results.

### Storage adapters

```typescript theme={null}
import { localStorageAdapter, fileStorage } from '@commerce-blocks/sdk'

// Browser (returns null if unavailable)
const browserAdapter = localStorageAdapter('my-cache-key')

// Node.js
import fs from 'fs'
const nodeAdapter = fileStorage('./cache.json', fs)
```

Custom adapter. Implement `StorageAdapter`:

```typescript theme={null}
interface StorageAdapter {
  read(): string | null
  write(data: string): void
  remove(): void
}

const adapter: StorageAdapter = {
  read: () => sessionStorage.getItem('key'),
  write: (data) => sessionStorage.setItem('key', data),
  remove: () => sessionStorage.removeItem('key'),
}
```

The `fileStorage` adapter accepts a minimal `FileSystem` interface so you can pass Node's `fs` module directly:

```typescript theme={null}
interface FileSystem {
  readFileSync(path: string, encoding: 'utf-8'): string
  writeFileSync(path: string, data: string, encoding: 'utf-8'): void
  unlinkSync(path: string): void
}
```

## Custom fetch

The SDK uses the global `fetch` by default. You can provide a custom fetch implementation for SSR, testing, or environments where `fetch` is not available:

```typescript theme={null}
import type { CustomFetch } from '@commerce-blocks/sdk'

type CustomFetch = (url: string, init?: RequestInit) => Promise<Response>
```

The SDK also exports `xhrFetch`, an XMLHttpRequest-based fetch alternative for environments where `fetch` is blocked by ad blockers or browser extensions:

```typescript theme={null}
import { xhrFetch, createClient } from '@commerce-blocks/sdk'

const { data: client, error } = createClient({
  token: 'your-token',
  sorts: [{ name: 'Featured', code: 'featured' }],
  facets: [{ name: 'Color', code: 'options.color' }],
  fetch: xhrFetch,
})

if (error) {
  console.error('Client init failed:', error.message)
}
```

## Signals

The SDK provides framework-agnostic reactive primitives (via `@preact/signals-core`). These work in any JavaScript environment with no framework dependency required:

```typescript theme={null}
import { signal, computed, effect, batch } from '@commerce-blocks/sdk'
import type { Signal, ReadonlySignal } from '@commerce-blocks/sdk'
```

You don't need to use signals directly. Every controller provides a `subscribe()` method and the SDK exports a standalone `subscribe()` utility that work without any signal imports. See [Framework Integration](/sdk/framework-integration) for patterns in React, Vue, Svelte, and more.

## Singleton access

After initialization, access the client anywhere:

```typescript theme={null}
import { getClient, isInitialized } from '@commerce-blocks/sdk'

if (isInitialized()) {
  const { data: client } = getClient()
  // Use client
}
```

## Technical details

* **Runtime**: Browser (ESM)
* **TypeScript**: Full type definitions included
* **Dependencies**: `@preact/signals-core`
* **Bundle**: Tree-shakeable ES modules
* **Caching**: Built-in LRU cache with configurable TTL

## Next steps

* [Client methods](/sdk/api-reference/client-methods)
* [Framework integration](/sdk/framework-integration)
