restate / v1.0.0

Affidabilità by design

Che cosa garantisce restate quando l’archivio è lento, fallisce o manca, e come leggere gli errori che segnala.

In questa paginaLe garanzieSalvataggi ordinatiProvaloQuando il caricamento fallisceSalva e chiudiNessun archivio disponibileValida e migra i dati salvatiUsa il tuo archivioLimiti e timeoutCodici di errore

Le garanzie

Questi comportamenti fanno parte del contratto della 1.0 e sono coperti dai test del pacchetto.

SituazioneChe cosa fa restate
Più salvataggi di filaLi esegue in ordine per ogni store; un salvataggio in coda scrive il valore più recente.
Un record non si è caricatoautoSave e i salvataggi in blocco lo saltano con LOAD_FAILED; solo un save() esplicito lo sostituisce.
Il componente viene smontato durante un salvataggioIl salvataggio richiesto termina; le scritture successive nello store distrutto vengono ignorate.
L’archivio non è disponibileLo store funziona in memoria, status().available è false, i salvataggi vengono rifiutati.
Un adattatore si bloccaL’operazione va in timeout dopo operationTimeoutMs e il lavoro successivo aspetta che l’adattatore finisca.
Troppo lavoro in sospesoLe nuove operazioni vengono rifiutate con QUEUE_FULL invece di crescere senza limiti.

Salvataggi ordinati

Le operazioni di uno store non si sovrappongono mai. Un salvataggio avviato mentre un altro aspetta prende il valore più nuovo, così salvare a ogni modifica scrive l’ultimo stato senza riempire la coda.

JavaScript / JSX
useDraft.set('A');
const first = useDraft.save(); // writes "A"
useDraft.set('B');
const second = useDraft.save(); // waits in the queue
useDraft.set('C');
const third = useDraft.save(); // joins the waiting save

await Promise.all([first, second, third]); // ['A', 'C', 'C'] — two writes

Provalo

Rallenta l’archivio, fai fallire le scritture o rimuovi del tutto l’archivio.

Preparazione dell’esempio…

Quando il caricamento fallisce

restateManager.ready viene rifiutato con BULK_OPERATION_FAILED ed elenca ogni store fallito. Finché quel record non si carica, autoSave e saveAll non lo sostituiscono e segnalano LOAD_FAILED.

Riprova con initialize() per tenere le modifiche e salvarle, chiama restore() per scartarle o save() per sovrascrivere il record di proposito.

JavaScript / JSX
try {
  await restateManager.ready;
} catch (error) {
  // BULK_OPERATION_FAILED: one entry per store that could not load.
  for (const { store, error: cause } of error.failures) {
    console.error(store.key, cause.code);
  }
}

Salva e chiudi

Un salvataggio richiesto prima dello smontaggio termina comunque, quindi un handler «Salva e chiudi» non deve aspettare.

JavaScript / JSX
function Document({ onClose }) {
  const useDraft = useRestateScope((scope) => persistedRestate('', { scope, key: 'draft' }));

  const saveAndClose = () => {
    useDraft.save(); // finishes even after this component unmounts
    onClose();
  };
  // …
}

Nessun archivio disponibile

Il rendering sul server e l’archivio bloccato dal browser non sono errori all’avvio. Controlla available per dire agli utenti che le modifiche restano solo in memoria.

JavaScript / JSX
const { available } = useDraft.status();

if (!available) {
  // Server rendering or blocked browser storage: the store works in memory
  // and save() rejects with STORAGE_UNAVAILABLE.
  showNotice('Changes are kept until you close this tab.');
}

Valida e migra i dati salvati

version, migrate e validate ti proteggono da record vecchi o corrotti. validate viene eseguito prima del salvataggio e dopo il ripristino o la migrazione.

JavaScript / JSX
import { persistedRestate } from '@kkwaenggwari/restate';

const useSettings = persistedRestate(
  { theme: 'system' },
  {
    key: 'settings',
    version: 2,
    migrate(value, from, to) {
      if (from === 1 && to === 2 && typeof value?.darkMode === 'boolean') {
        return { theme: value.darkMode ? 'dark' : 'light' };
      }
      throw new Error('Unsupported stored version');
    },
    validate: (value) => ['system', 'light', 'dark'].includes(value?.theme),
  },
);

Usa il tuo archivio

Va bene qualsiasi oggetto con getItem, setItem e removeItem. I metodi possono restituire valori o Promise; isAvailable è opzionale.

JavaScript / JSX
import { persistedRestate } from '@kkwaenggwari/restate';

const sessionStorageAdapter = {
  isAvailable: () => typeof sessionStorage !== 'undefined',
  getItem: (key) => sessionStorage.getItem(key),
  setItem: (key, value) => sessionStorage.setItem(key, value),
  removeItem: (key) => sessionStorage.removeItem(key),
};

export const useFilters = persistedRestate(
  { query: '' },
  {
    key: 'filters',
    storage: sessionStorageAdapter,
  },
);

Limiti e timeout

Regola quanto può durare un’operazione, quante possono aspettare e quanto può essere grande un valore.

JavaScript / JSX
persistedRestate(value, {
  key: 'draft',
  operationTimeoutMs: 10_000, // default 30000
  maxPendingOperations: 64, // default 256
  maxStorageCharacters: 1_000_000,
});

Codici di errore

Gli errori creati da restate hanno name RestateError, un code e, per gli store salvati, key. Gli adattatori di archiviazione e i tuoi callback possono rifiutare con errori propri.

CodiceSignificato
BULK_OPERATION_FAILEDUna chiamata in blocco come restateManager.ready o saveAll ha avuto errori; vedi error.failures.
INDEXEDDB_ABORTEDUna transazione IndexedDB è stata annullata.
INDEXEDDB_BLOCKEDL’apertura del database è stata bloccata da una connessione in un’altra tab.
INDEXEDDB_CONNECTION_CLOSINGLa connessione al database si stava chiudendo quando è iniziata la richiesta.
INDEXEDDB_OPEN_FAILEDImpossibile aprire il database.
INDEXEDDB_REQUEST_FAILEDUna richiesta IndexedDB non è riuscita.
INDEXEDDB_STORE_MISSINGL’object store non esiste in un database già creato.
INVALID_STORAGE_RECORDUn record salvato non è un record restate valido.
INVALID_STORED_VALUEUn valore non ha superato validate.
LIFECYCLE_LIMITUn updater continuava ad avviarsi e fermarsi.
LOAD_FAILEDUn record non si è potuto caricare, quindi un salvataggio automatico o in blocco non l’ha sostituito.
MMKV_UNAVAILABLEImpossibile caricare react-native-mmkv.
MULTIPLE_ERRORSPiù callback sono falliti in un’operazione; vedi error.errors.
NOTIFICATION_LIMITGli osservatori continuavano a programmare modifiche in un ciclo.
OBSERVER_ERRORUn listener o un callback del ciclo di vita ha lanciato un errore.
OPERATION_ABORTEDUn’operazione di archiviazione è stata annullata.
QUEUE_FULLIn attesa c’erano più operazioni di quante ne consenta maxPendingOperations.
REENTRANT_SETTERUn updater di stato ha provato a cambiare lo stesso store mentre era in esecuzione.
SCOPE_DESTROYEDÈ stato usato uno scope distrutto per creare store.
SEQUENCE_EXHAUSTEDUna sequenza interna ha esaurito gli identificatori.
STORAGE_BLOCKEDUna chiamata precedente all’adattatore non si è conclusa dopo un timeout o un annullamento.
STORAGE_TIMEOUTUn’operazione ha impiegato più di operationTimeoutMs.
STORAGE_UNAVAILABLEQui l’archivio non può essere usato; lo store continua a funzionare in memoria.
STORAGE_VALUE_TOO_LARGEIl valore codificato supera maxStorageCharacters.
STORAGE_VERSION_MISMATCHUn record ha un’altra versione e nessuna funzione migrate la gestisce.
STORE_DESTROYEDCi si è iscritti a uno store distrutto o gli si è chiesto di usare l’archivio.

Cerca nella documentazione

Cerca nei titoli, nelle descrizioni e nel testo di tutte le guide.