restate / v1.0.0
Betrouwbaarheid by design
Wat restate garandeert als opslag traag is, faalt of ontbreekt, en hoe je de gemelde fouten leest.
Op deze pagina
De garantiesSaves op volgordeProbeer hetAls laden misluktOpslaan en sluitenGeen opslag beschikbaarOpgeslagen data valideren en migrerenJe eigen opslag gebruikenLimieten en time-outsFoutcodesDe garanties
Dit gedrag hoort bij het contract van 1.0 en wordt gedekt door de tests van het pakket.
| Situatie | Wat restate doet |
|---|---|
Meerdere saves achter elkaar | Voert ze per store op volgorde uit; een save in de wachtrij schrijft de nieuwste waarde. |
Een record laadde niet | autoSave en bulksaves slaan het over met LOAD_FAILED; alleen een expliciete save() vervangt het. |
Het component unmount tijdens een save | De aangevraagde save wordt afgemaakt; latere schrijfacties naar de vernietigde store worden genegeerd. |
Opslag is niet beschikbaar | De store werkt in het geheugen, status().available is false en saves worden geweigerd. |
Een adapter loopt vast | De bewerking verloopt na operationTimeoutMs en later werk wacht tot de adapter klaar is. |
Te veel werk in de wachtrij | Nieuwe bewerkingen worden geweigerd met QUEUE_FULL in plaats van onbeperkt te groeien. |
Saves op volgorde
Bewerkingen van één store overlappen nooit. Een save die start terwijl een andere wacht, neemt de nieuwste waarde, dus opslaan bij elke wijziging schrijft de laatste state zonder de wachtrij te vullen.
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 writesProbeer het
Maak de opslag trager, laat schrijfacties mislukken of haal de opslag helemaal weg.
Voorbeeld voorbereiden…
Als laden mislukt
restateManager.ready wordt geweigerd met BULK_OPERATION_FAILED en noemt elke mislukte store. Totdat dat record laadt, vervangen autoSave en saveAll het niet en melden ze LOAD_FAILED.
Probeer opnieuw met initialize() om bewerkingen te houden en op te slaan, roep restore() aan om ze te verwerpen, of save() om het record bewust te overschrijven.
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);
}
}Opslaan en sluiten
Een save die vóór de unmount is aangevraagd, wordt toch afgemaakt, dus een handler voor „Opslaan en sluiten” hoeft niet te wachten.
function Document({ onClose }) {
const useDraft = useRestateScope((scope) => persistedRestate('', { scope, key: 'draft' }));
const saveAndClose = () => {
useDraft.save(); // finishes even after this component unmounts
onClose();
};
// …
}Opgeslagen data valideren en migreren
version, migrate en validate beschermen je tegen oude of beschadigde records. validate draait vóór het opslaan en na terugzetten of migreren.
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),
},
);Je eigen opslag gebruiken
Elk object met getItem, setItem en removeItem werkt. De methoden mogen waarden of een Promise teruggeven; isAvailable is optioneel.
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,
},
);Limieten en time-outs
Stel in hoe lang een bewerking mag duren, hoeveel er mogen wachten en hoe groot een waarde mag zijn.
persistedRestate(value, {
key: 'draft',
operationTimeoutMs: 10_000, // default 30000
maxPendingOperations: 64, // default 256
maxStorageCharacters: 1_000_000,
});Foutcodes
Fouten die restate aanmaakt hebben name RestateError, een code en, bij opgeslagen stores, key. Opslagadapters en je eigen callbacks kunnen weigeren met eigen fouten.
| Code | Betekenis |
|---|---|
BULK_OPERATION_FAILED | Een bulkaanroep zoals restateManager.ready of saveAll had fouten; zie error.failures. |
INDEXEDDB_ABORTED | Een IndexedDB-transactie is afgebroken. |
INDEXEDDB_BLOCKED | Het openen van de database werd geblokkeerd door een verbinding in een ander tabblad. |
INDEXEDDB_CONNECTION_CLOSING | De databaseverbinding werd gesloten toen het verzoek begon. |
INDEXEDDB_OPEN_FAILED | De database kon niet worden geopend. |
INDEXEDDB_REQUEST_FAILED | Een IndexedDB-verzoek is mislukt. |
INDEXEDDB_STORE_MISSING | De object store ontbreekt in een al aangemaakte database. |
INVALID_STORAGE_RECORD | Een opgeslagen record is geen geldig restate-record. |
INVALID_STORED_VALUE | Een waarde kwam niet door validate. |
LIFECYCLE_LIMIT | Een updater bleef starten en stoppen. |
LOAD_FAILED | Een record kon niet laden, dus een automatische of bulksave heeft het niet vervangen. |
MMKV_UNAVAILABLE | react-native-mmkv kon niet worden geladen. |
MULTIPLE_ERRORS | Meerdere callbacks mislukten in één bewerking; zie error.errors. |
NOTIFICATION_LIMIT | Observers bleven in een lus wijzigingen inplannen. |
OBSERVER_ERROR | Een listener of lifecycle-callback gooide een fout. |
OPERATION_ABORTED | Een opslagbewerking is afgebroken. |
QUEUE_FULL | Er wachtten meer bewerkingen dan maxPendingOperations toestaat. |
REENTRANT_SETTER | Een state-updater probeerde dezelfde store te wijzigen terwijl hij draaide. |
SCOPE_DESTROYED | Een vernietigde scope werd gebruikt om stores aan te maken. |
SEQUENCE_EXHAUSTED | Een interne reeks had geen id's meer. |
STORAGE_BLOCKED | Een eerdere adapteraanroep werd na een time-out of afbreking niet afgerond. |
STORAGE_TIMEOUT | Een bewerking duurde langer dan operationTimeoutMs. |
STORAGE_UNAVAILABLE | Opslag kan hier niet worden gebruikt; de store blijft in het geheugen werken. |
STORAGE_VALUE_TOO_LARGE | De gecodeerde waarde overschrijdt maxStorageCharacters. |
STORAGE_VERSION_MISMATCH | Een record heeft een andere versie en geen migrate-functie die het afhandelt. |
STORE_DESTROYED | Er werd geabonneerd op een vernietigde store of die werd gevraagd opslag te gebruiken. |