restate / v1.0.0

Надеждност by design

Какво гарантира restate, когато хранилището е бавно, отказва или липсва, и как да четете грешките, които съобщава.

На тази страницаГаранциитеПодредени запазванияОпитайтеКогато зареждането се провалиЗапази и затвориНяма налично хранилищеВалидиране и мигриране на запазени данниСобствено хранилищеОграничения и изчакванеКодове на грешки

Гаранциите

Това поведение е част от договора на 1.0 и е покрито от тестовете на пакета.

СитуацияКакво прави restate
Няколко запазвания едно след другоИзпълнява ги по ред за всеки store; запазване в опашката записва най-новата стойност.
Запис не се е заредилautoSave и груповите запазвания го пропускат с LOAD_FAILED; замества го само изрично save().
Компонентът се демонтира по време на запазванеПоисканото запазване завършва; по-късните записи в унищожения store се игнорират.
Хранилището е недостъпноStore работи в паметта, status().available е false, а запазванията се отхвърлят.
Адаптерът зависваОперацията изтича след operationTimeoutMs, а следващата работа чака, докато адаптерът приключи.
Твърде много чакаща работаНовите операции се отхвърлят с QUEUE_FULL, вместо да растат безкрайно.

Подредени запазвания

Операциите на един store никога не се застъпват. Запазване, започнало, докато друго чака, взема най-новата стойност, така че запазването при всяка промяна записва последното състояние, без да пълни опашката.

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

Опитайте

Забавете хранилището, накарайте записите да се провалят или махнете хранилището изцяло.

Подготовка на примера…

Когато зареждането се провали

restateManager.ready се отхвърля с BULK_OPERATION_FAILED и изброява всеки store с грешка. Докато този запис не се зареди, autoSave и saveAll не го заменят и съобщават LOAD_FAILED.

Опитайте отново с initialize(), за да запазите промените и да ги съхраните, извикайте restore(), за да ги отхвърлите, или save(), за да презапишете записа нарочно.

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

Запази и затвори

Запазване, поискано преди демонтиране, пак завършва, така че обработчик за „Запази и затвори“ не трябва да чака.

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

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

Няма налично хранилище

Рендерирането на сървъра и блокираното от браузъра хранилище не са грешки при стартиране. Проверявайте available, за да кажете на потребителите, че промените остават само в паметта.

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

Валидиране и мигриране на запазени данни

version, migrate и validate ви пазят от стари или повредени записи. validate се изпълнява преди запазване и след възстановяване или миграция.

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

Собствено хранилище

Става всеки обект с getItem, setItem и removeItem. Методите могат да връщат стойности или Promise; isAvailable не е задължителен.

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

Ограничения и изчакване

Настройте колко може да продължи една операция, колко операции могат да чакат и колко голяма може да е стойността.

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

Кодове на грешки

Грешките, създадени от restate, имат name RestateError, code и, при запазваните store, key. Адаптерите за хранилище и вашите callback-и могат да отхвърлят със собствени грешки.

КодЗначение
BULK_OPERATION_FAILEDГрупово извикване като restateManager.ready или saveAll е имало грешки; вижте error.failures.
INDEXEDDB_ABORTEDТранзакция на IndexedDB е прекъсната.
INDEXEDDB_BLOCKEDОтварянето на базата данни е блокирано от връзка в друг раздел.
INDEXEDDB_CONNECTION_CLOSINGВръзката с базата данни се е затваряла, когато заявката е започнала.
INDEXEDDB_OPEN_FAILEDБазата данни не можа да се отвори.
INDEXEDDB_REQUEST_FAILEDЗаявка към IndexedDB не успя.
INDEXEDDB_STORE_MISSINGВ вече създадена база данни липсва object store.
INVALID_STORAGE_RECORDЗапазеният запис не е валиден запис на restate.
INVALID_STORED_VALUEСтойност не е преминала validate.
LIFECYCLE_LIMITUpdater продължаваше да стартира и спира.
LOAD_FAILEDЗапис не можа да се зареди, затова автоматично или групово запазване не го замени.
MMKV_UNAVAILABLEreact-native-mmkv не можа да се зареди.
MULTIPLE_ERRORSВ една операция са се провалили няколко callback-а; вижте error.errors.
NOTIFICATION_LIMITНаблюдателите продължаваха да планират промени в цикъл.
OBSERVER_ERRORСлушател или callback на жизнения цикъл е хвърлил грешка.
OPERATION_ABORTEDОперация с хранилището е отменена.
QUEUE_FULLЧакащите операции са повече, отколкото позволява maxPendingOperations.
REENTRANT_SETTERUpdater на състоянието е опитал да промени същия store, докато се изпълнява.
SCOPE_DESTROYEDУнищожен scope е използван за създаване на store.
SEQUENCE_EXHAUSTEDВътрешна последователност е изчерпала идентификаторите.
STORAGE_BLOCKEDПредишно извикване на адаптера не е приключило след изтичане на времето или отмяна.
STORAGE_TIMEOUTОперация е продължила по-дълго от operationTimeoutMs.
STORAGE_UNAVAILABLEТук хранилището не може да се използва; store продължава да работи в паметта.
STORAGE_VALUE_TOO_LARGEКодираната стойност надхвърля maxStorageCharacters.
STORAGE_VERSION_MISMATCHЗаписът има друга версия и никоя функция migrate не я обработва.
STORE_DESTROYEDИма абониране за унищожен store или той е помолен да използва хранилище.

Търсене в документацията

Търсене в заглавията, описанията и текста на всички ръководства.