restate / v1.0.0

Spolehlivost by design

Co restate zaručuje, když je úložiště pomalé, selhává nebo chybí, a jak číst chyby, které hlásí.

Na této stránceZárukyUložení v pořadíVyzkoušejteKdyž načítání selžeUložit a zavřítŽádné úložiště k dispoziciValidace a migrace uložených datVlastní úložištěLimity a časové limityKódy chyb

Záruky

Toto chování je součástí kontraktu 1.0 a pokrývají ho testy balíčku.

SituaceCo restate udělá
Několik uložení za sebouProvede je v pořadí pro každý store; uložení ve frontě zapíše nejnovější hodnotu.
Záznam se nenačetlautoSave a hromadná uložení ho přeskočí s LOAD_FAILED; nahradí ho jen explicitní save().
Komponenta se během uložení odpojíVyžádané uložení se dokončí; pozdější zápisy do zničeného store se ignorují.
Úložiště není dostupnéStore funguje v paměti, status().available je false a uložení se odmítají.
Adaptér se zasekneOperaci vyprší čas po operationTimeoutMs a další práce počká, až adaptér skončí.
Příliš mnoho čekající práceNové operace se odmítnou s QUEUE_FULL, místo aby fronta rostla bez omezení.

Uložení v pořadí

Operace jednoho store se nikdy nepřekrývají. Uložení spuštěné, zatímco jiné čeká, vezme nejnovější hodnotu, takže ukládání při každé změně zapíše poslední stav bez zahlcení fronty.

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

Vyzkoušejte

Zpomalte úložiště, nechte zápisy selhávat nebo úložiště úplně odeberte.

Příprava příkladu…

Když načítání selže

restateManager.ready se odmítne s BULK_OPERATION_FAILED a vypíše každý store, který selhal. Dokud se ten záznam nenačte, autoSave a saveAll ho nenahradí a nahlásí LOAD_FAILED.

Zkuste to znovu přes initialize(), chcete-li úpravy zachovat a uložit, zavolejte restore(), chcete-li je zahodit, nebo save(), chcete-li záznam záměrně přepsat.

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);
  }
}

Uložit a zavřít

Uložení vyžádané před odpojením se i tak dokončí, takže obsluha „Uložit a zavřít“ nemusí čekat.

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

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

Žádné úložiště k dispozici

Renderování na serveru a úložiště zablokované prohlížečem nejsou chyby při spuštění. Kontrolujte available, abyste uživatelům řekli, že úpravy zůstávají jen v paměti.

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.');
}

Validace a migrace uložených dat

version, migrate a validate vás chrání před starými nebo poškozenými záznamy. validate se spouští před uložením a po obnovení či migraci.

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),
  },
);

Vlastní úložiště

Poslouží jakýkoli objekt s getItem, setItem a removeItem. Metody mohou vracet hodnoty nebo Promise; isAvailable je volitelné.

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,
  },
);

Limity a časové limity

Nastavte, jak dlouho smí operace trvat, kolik jich smí čekat a jak velká smí být hodnota.

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

Kódy chyb

Chyby vytvořené restate mají name RestateError, code a u ukládaných store také key. Adaptéry úložiště a vaše callbacky mohou odmítat vlastními chybami.

KódVýznam
BULK_OPERATION_FAILEDHromadné volání jako restateManager.ready nebo saveAll mělo chyby; viz error.failures.
INDEXEDDB_ABORTEDTransakce IndexedDB byla přerušena.
INDEXEDDB_BLOCKEDOtevření databáze zablokovalo připojení v jiné kartě.
INDEXEDDB_CONNECTION_CLOSINGPřipojení k databázi se zavíralo, když požadavek začal.
INDEXEDDB_OPEN_FAILEDDatabázi se nepodařilo otevřít.
INDEXEDDB_REQUEST_FAILEDPožadavek IndexedDB selhal.
INDEXEDDB_STORE_MISSINGV již vytvořené databázi chybí object store.
INVALID_STORAGE_RECORDUložený záznam není platný záznam restate.
INVALID_STORED_VALUEHodnota neprošla validate.
LIFECYCLE_LIMITUpdater se opakovaně spouštěl a zastavoval.
LOAD_FAILEDZáznam se nepodařilo načíst, takže ho automatické ani hromadné uložení nenahradilo.
MMKV_UNAVAILABLEreact-native-mmkv se nepodařilo načíst.
MULTIPLE_ERRORSV jedné operaci selhalo více callbacků; viz error.errors.
NOTIFICATION_LIMITPozorovatelé v cyklu stále plánovali změny.
OBSERVER_ERRORPosluchač nebo callback životního cyklu vyhodil chybu.
OPERATION_ABORTEDOperace s úložištěm byla zrušena.
QUEUE_FULLČekalo více operací, než dovoluje maxPendingOperations.
REENTRANT_SETTERUpdater stavu se během svého běhu pokusil změnit tentýž store.
SCOPE_DESTROYEDK vytvoření store byl použit zničený scope.
SEQUENCE_EXHAUSTEDVnitřní sekvenci došly identifikátory.
STORAGE_BLOCKEDPředchozí volání adaptéru se po vypršení času nebo zrušení nedokončilo.
STORAGE_TIMEOUTOperace trvala déle než operationTimeoutMs.
STORAGE_UNAVAILABLEÚložiště zde nelze použít; store dál funguje v paměti.
STORAGE_VALUE_TOO_LARGEZakódovaná hodnota překračuje maxStorageCharacters.
STORAGE_VERSION_MISMATCHZáznam má jinou verzi a žádná funkce migrate ji neobsluhuje.
STORE_DESTROYEDDošlo k odběru zničeného store nebo byl požádán o použití úložiště.

Hledat v dokumentaci

Hledejte v nadpisech, popisech a textu všech průvodců.