restate / v1.0.0
Pålidelighed by design
Hvad restate garanterer, når lageret er langsomt, fejler eller mangler, og hvordan du læser de fejl, det melder.
På denne side
GarantierneOrdnede gemPrøv detNår indlæsningen fejlerGem og lukIntet lager tilgængeligtValidér og migrér gemte dataBrug dit eget lagerGrænser og timeoutsFejlkoderGarantierne
Denne adfærd er en del af 1.0-kontrakten og er dækket af pakkens tests.
| Situation | Hvad restate gør |
|---|---|
Flere gem i træk | Kører dem i rækkefølge pr. store; et gem i kø skriver den nyeste værdi. |
En post blev ikke indlæst | autoSave og masse-gem springer den over med LOAD_FAILED; kun et eksplicit save() erstatter den. |
Komponenten afmonteres under et gem | Det anmodede gem gøres færdigt; senere skrivninger til den nedlagte store ignoreres. |
Lageret er utilgængeligt | Storen kører i hukommelsen, status().available er false, og gem afvises. |
En adapter hænger | Handlingen får timeout efter operationTimeoutMs, og senere arbejde venter, til adapteren er færdig. |
For meget ventende arbejde | Nye handlinger afvises med QUEUE_FULL i stedet for at vokse uden grænse. |
Ordnede gem
En stores handlinger overlapper aldrig. Et gem, der starter, mens et andet venter, tager den nyeste værdi, så gem ved hver ændring skriver den seneste state uden at fylde køen.
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 writesPrøv det
Gør lageret langsommere, lad skrivninger fejle, eller fjern lageret helt.
Forbereder eksemplet…
Når indlæsningen fejler
restateManager.ready afvises med BULK_OPERATION_FAILED og oplister hver store, der fejlede. Indtil den post indlæses, erstatter autoSave og saveAll den ikke og melder LOAD_FAILED.
Prøv igen med initialize() for at beholde ændringerne og gemme dem, kald restore() for at kassere dem, eller save() for bevidst at overskrive posten.
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);
}
}Gem og luk
Et gem, der blev bedt om før unmount, gøres stadig færdigt, så en handler til »Gem og luk« behøver ikke vente.
function Document({ onClose }) {
const useDraft = useRestateScope((scope) => persistedRestate('', { scope, key: 'draft' }));
const saveAndClose = () => {
useDraft.save(); // finishes even after this component unmounts
onClose();
};
// …
}Validér og migrér gemte data
version, migrate og validate beskytter dig mod gamle eller ødelagte poster. validate kører før gem og efter gendannelse eller migrering.
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),
},
);Brug dit eget lager
Ethvert objekt med getItem, setItem og removeItem virker. Metoderne kan returnere værdier eller Promise; isAvailable er valgfri.
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 og timeouts
Justér, hvor længe en handling må tage, hvor mange der må vente, og hvor stor en værdi må være.
persistedRestate(value, {
key: 'draft',
operationTimeoutMs: 10_000, // default 30000
maxPendingOperations: 64, // default 256
maxStorageCharacters: 1_000_000,
});Fejlkoder
Fejl, som restate opretter, har name RestateError, en code og, for gemte stores, key. Lageradaptere og dine egne callbacks kan afvise med deres egne fejl.
| Kode | Betydning |
|---|---|
BULK_OPERATION_FAILED | Et massekald som restateManager.ready eller saveAll havde fejl; se error.failures. |
INDEXEDDB_ABORTED | En IndexedDB-transaktion blev afbrudt. |
INDEXEDDB_BLOCKED | Åbning af databasen blev blokeret af en forbindelse i en anden fane. |
INDEXEDDB_CONNECTION_CLOSING | Databaseforbindelsen var ved at lukke, da anmodningen startede. |
INDEXEDDB_OPEN_FAILED | Databasen kunne ikke åbnes. |
INDEXEDDB_REQUEST_FAILED | En IndexedDB-anmodning mislykkedes. |
INDEXEDDB_STORE_MISSING | Object store mangler i en allerede oprettet database. |
INVALID_STORAGE_RECORD | En gemt post er ikke en gyldig restate-post. |
INVALID_STORED_VALUE | En værdi bestod ikke validate. |
LIFECYCLE_LIMIT | En updater blev ved med at starte og stoppe. |
LOAD_FAILED | En post kunne ikke indlæses, så et automatisk gem eller masse-gem erstattede den ikke. |
MMKV_UNAVAILABLE | react-native-mmkv kunne ikke indlæses. |
MULTIPLE_ERRORS | Flere callbacks fejlede i én handling; se error.errors. |
NOTIFICATION_LIMIT | Observatører blev ved med at planlægge ændringer i en løkke. |
OBSERVER_ERROR | En listener eller livscyklus-callback kastede en fejl. |
OPERATION_ABORTED | En lagerhandling blev afbrudt. |
QUEUE_FULL | Der ventede flere handlinger, end maxPendingOperations tillader. |
REENTRANT_SETTER | En state-updater forsøgte at ændre den samme store, mens den kørte. |
SCOPE_DESTROYED | Et nedlagt scope blev brugt til at oprette stores. |
SEQUENCE_EXHAUSTED | En intern sekvens løb tør for id'er. |
STORAGE_BLOCKED | Et tidligere adapterkald blev ikke afsluttet efter timeout eller afbrydelse. |
STORAGE_TIMEOUT | En handling tog længere tid end operationTimeoutMs. |
STORAGE_UNAVAILABLE | Lageret kan ikke bruges her; storen kører videre i hukommelsen. |
STORAGE_VALUE_TOO_LARGE | Den kodede værdi overstiger maxStorageCharacters. |
STORAGE_VERSION_MISMATCH | En post har en anden version, og ingen migrate-funktion håndterer den. |
STORE_DESTROYED | Der blev abonneret på en nedlagt store, eller den blev bedt om at bruge lager. |