restate / v1.0.0

Tillförlitlighet by design

Vad restate garanterar när lagringen är långsam, fallerar eller saknas, och hur du läser felen den rapporterar.

På den här sidanGarantiernaOrdnade sparningarProvaNär inläsningen misslyckasSpara och stängIngen lagring tillgängligValidera och migrera sparad dataAnvänd din egen lagringGränser och timeoutsFelkoder

Garantierna

De här beteendena ingår i 1.0-kontraktet och täcks av paketets tester.

SituationVad restate gör
Flera sparningar i radKör dem i ordning per store; en köad sparning skriver det senaste värdet.
En post lästes inte inautoSave och massparningar hoppar över den med LOAD_FAILED; bara ett explicit save() ersätter den.
Komponenten avmonteras under en sparningDen begärda sparningen slutförs; senare skrivningar till den förstörda storen ignoreras.
Lagringen är otillgängligStoren fungerar i minnet, status().available är false och sparningar avvisas.
En adapter hänger sigÅtgärden får timeout efter operationTimeoutMs och senare arbete väntar tills adaptern är klar.
För mycket väntande arbeteNya åtgärder avvisas med QUEUE_FULL i stället för att växa utan gräns.

Ordnade sparningar

En stores åtgärder överlappar aldrig. En sparning som startar medan en annan väntar tar det nyaste värdet, så att spara vid varje ändring skriver det senaste tillståndet utan att fylla kön.

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

Prova

Gör lagringen långsammare, låt skrivningar misslyckas eller ta bort lagringen helt.

Förbereder exemplet…

När inläsningen misslyckas

restateManager.ready avvisas med BULK_OPERATION_FAILED och listar varje store som misslyckades. Tills den posten läses in ersätter autoSave och saveAll den inte och rapporterar LOAD_FAILED.

Försök igen med initialize() för att behålla ändringarna och spara dem, anropa restore() för att kasta dem eller save() för att medvetet skriva över posten.

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

Spara och stäng

En sparning som begärts före unmount slutförs ändå, så en hanterare för ”Spara och stäng” behöver inte vänta.

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

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

Ingen lagring tillgänglig

Serverrendering och lagring som webbläsaren blockerar är inga startfel. Kontrollera available för att berätta för användarna att ändringarna bara finns i minnet.

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

Validera och migrera sparad data

version, migrate och validate skyddar dig mot gamla eller trasiga poster. validate körs före sparning och efter återställning eller migrering.

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

Använd din egen lagring

Vilket objekt som helst med getItem, setItem och removeItem fungerar. Metoderna kan returnera värden eller Promise; isAvailable är valfri.

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

Gränser och timeouts

Justera hur länge en åtgärd får ta, hur många som får vänta och hur stort ett värde får vara.

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

Felkoder

Fel som restate skapar har name RestateError, en code och, för sparade stores, key. Lagringsadaptrar och dina egna callbacks kan avvisa med egna fel.

KodBetydelse
BULK_OPERATION_FAILEDEtt massanrop som restateManager.ready eller saveAll hade fel; se error.failures.
INDEXEDDB_ABORTEDEn IndexedDB-transaktion avbröts.
INDEXEDDB_BLOCKEDAtt öppna databasen blockerades av en anslutning i en annan flik.
INDEXEDDB_CONNECTION_CLOSINGDatabasanslutningen höll på att stängas när begäran startade.
INDEXEDDB_OPEN_FAILEDDatabasen kunde inte öppnas.
INDEXEDDB_REQUEST_FAILEDEn IndexedDB-begäran misslyckades.
INDEXEDDB_STORE_MISSINGObject store saknas i en redan skapad databas.
INVALID_STORAGE_RECORDEn sparad post är inte en giltig restate-post.
INVALID_STORED_VALUEEtt värde klarade inte validate.
LIFECYCLE_LIMITEn updater fortsatte att starta och stoppa.
LOAD_FAILEDEn post kunde inte läsas in, så en automatisk eller massparning ersatte den inte.
MMKV_UNAVAILABLEreact-native-mmkv kunde inte läsas in.
MULTIPLE_ERRORSFlera callbacks misslyckades i en åtgärd; se error.errors.
NOTIFICATION_LIMITObservatörer fortsatte att schemalägga ändringar i en loop.
OBSERVER_ERROREn lyssnare eller livscykel-callback kastade ett fel.
OPERATION_ABORTEDEn lagringsåtgärd avbröts.
QUEUE_FULLFler åtgärder väntade än maxPendingOperations tillåter.
REENTRANT_SETTEREn state-updater försökte ändra samma store medan den kördes.
SCOPE_DESTROYEDEtt förstört scope användes för att skapa stores.
SEQUENCE_EXHAUSTEDEn intern sekvens fick slut på id:n.
STORAGE_BLOCKEDEtt tidigare adapteranrop slutfördes inte efter timeout eller avbrott.
STORAGE_TIMEOUTEn åtgärd tog längre tid än operationTimeoutMs.
STORAGE_UNAVAILABLELagring kan inte användas här; storen fortsätter att fungera i minnet.
STORAGE_VALUE_TOO_LARGEDet kodade värdet överskrider maxStorageCharacters.
STORAGE_VERSION_MISMATCHEn post har en annan version och ingen migrate-funktion hanterar den.
STORE_DESTROYEDEn förstörd store prenumererades på eller ombads använda lagring.

Sök i dokumentationen

Sök i rubriker, beskrivningar och text i alla guider.