Skip to main content

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 and storage

The client exposes a reactive cache:
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

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

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:
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:
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:
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:
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:
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 for patterns in React, Vue, Svelte, and more.

Singleton access

After initialization, access the client anywhere:
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