Domain

CacheMetadata

Value objects immutabili per la gestione cache — elementi cached, metadati temporali, snapshot stato, configurazione stale-while-revalidate e risposte HTTP cached.

Cos'è

CacheMetadata è un modulo di value objects immutabili che modellano i concetti di dominio della cache: singolo elemento memorizzato, metadati temporali, snapshot dello stato globale, configurazione del refresh in background (pattern stale-while-revalidate) e struttura compatta di risposte HTTP cached.

import type {
  CacheItem,
  CacheMetadata,
  CacheState,
  BackgroundRefreshConfig,
  CachedResponse,
} from '@pzeta/postgrest'

Tipi

CacheItem<T>

Singolo record nella cache: dato + metadati temporali.

interface CacheItem<T> {
  /** Dato originale memorizzato in cache */
  data: T
  /** Timestamp Unix (ms) di quando l'elemento è stato inserito */
  timestamp: number
  /** Timestamp Unix (ms) di scadenza, o null se non scade */
  expiry: number | null
}
CampoTipoRequiredDescrizione
dataTPayload memorizzato (tipo generico)
timestampnumberInserimento (Unix ms)
expirynumber | nullScadenza (Unix ms) — null = cache permanente
const cachedUser: CacheItem<User> = {
  data: { id: 1, name: 'Mario Rossi' },
  timestamp: Date.now(),
  expiry: Date.now() + 3600000, // 1 ora
}

CacheMetadata

Solo i metadati temporali senza il dato — utile per verificare validità senza deserializzare.

interface CacheMetadata {
  timestamp: number
  expiry: number | null
}
function isValid(metadata: CacheMetadata): boolean {
  if (metadata.expiry === null) return true
  return Date.now() < metadata.expiry
}

function getAgeMs(metadata: CacheMetadata): number {
  return Date.now() - metadata.timestamp
}

CacheState

Snapshot completo della cache. Utile per serializzazione, debug, migrazione tra strategie di storage.

interface CacheState {
  items: Record<string, CacheItem<unknown>>
}
const state: CacheState = {
  items: {
    'users:1': { data: { id: 1 }, timestamp: 1700000000000, expiry: null },
    'users:2': { data: { id: 2 }, timestamp: 1700000001000, expiry: 1700003600000 },
  },
}

const count = Object.keys(state.items).length
const serialized = JSON.stringify(state)

BackgroundRefreshConfig

Configurazione del pattern stale-while-revalidate: il client restituisce dati cached mentre li aggiorna in background, migliorando la perceived performance senza sacrificare la freschezza.

interface BackgroundRefreshConfig {
  enabled: boolean
  threshold: number  // 0-100 (%)
  maxAge: number     // ms
}
CampoTipoRequiredDescrizione
enabledbooleanAbilita/disabilita il background refresh
thresholdnumber% di TTL consumato prima di avviare il refresh in background (es. 75 → quando resta il 25% del TTL)
maxAgenumberEtà massima (ms) oltre la quale si forza refresh sincrono

Algoritmo

1. Dato in cache && età < threshold% di TTL → restituisci cached
2. Dato in cache && età ≥ threshold% && età < maxAge → restituisci cached + refresh background
3. Dato in cache && età ≥ maxAge → attendi refresh sincrono
4. Dato non in cache → fetch sincrono

Esempi

// Dati frequentemente aggiornati
const frequentRefresh: BackgroundRefreshConfig = {
  enabled: true,
  threshold: 75,
  maxAge: 3600000, // max 1 ora
}

// Dati statici
const rareRefresh: BackgroundRefreshConfig = {
  enabled: true,
  threshold: 90,
  maxAge: 86400000, // max 24 ore
}

// Disabilitato (sempre fresh fetch su miss/expiry)
const noBackground: BackgroundRefreshConfig = {
  enabled: false,
  threshold: 0,
  maxAge: 0,
}
PostgRESTClient.init() configura BackgroundRefreshConfig con enabled: true, threshold: 75, maxAge: cacheTTL. Per disabilitare o personalizzare accedi a client.getCacheService().init({...}).

CachedResponse<T>

Risposta HTTP cached compatta. Contiene solo le informazioni minime per ricostruire la risposta originale.

interface CachedResponse<T> {
  data: T
  status: number
  statusText: string
  config: {
    url?: string
    method?: string
    baseURL?: string
    params?: Record<string, unknown>
  }
  timestamp: number
  expiry: number | null
}
CampoTipoRequiredDescrizione
dataTBody della risposta HTTP
statusnumberHTTP status code
statusTextstringHTTP status text
config.urlstringURL relativo della richiesta
config.methodstringMetodo HTTP
config.baseURLstringBase URL dell'API
config.paramsRecord<string, unknown>Query parameters
timestampnumberQuando è stata cached (Unix ms)
expirynumber | nullScadenza (Unix ms) o null
const cached: CachedResponse<User[]> = {
  data: [{ id: 1, name: 'Mario' }],
  status: 200,
  statusText: 'OK',
  config: { url: '/users', method: 'GET', baseURL: 'https://api.example.com' },
  timestamp: Date.now(),
  expiry: Date.now() + 300000,
}

const isStillValid = cached.expiry === null || cached.expiry > Date.now()

TTL e staleness — concetti chiave

ConcettoSignificato
TTLTime-To-Live: durata di validità in ms (expiry = timestamp + TTL)
StaleElemento ancora in cache ma con TTL parzialmente consumato (≥ threshold%)
ExpiredElemento con Date.now() > expiry — non più servibile
FreshElemento appena cached o ancora sotto la soglia threshold
maxAgeLimite assoluto oltre il quale si attende refresh sincrono anche con dato in cache

Tipi correlati