restate / v1.0.0

Tin cậy từ thiết kế

restate bảo đảm điều gì khi bộ nhớ lưu trữ chậm, thất bại hoặc không có, và cách đọc các lỗi nó báo.

Trên trang nàyBảo đảmLưu tuần tựThử ngayKhi tải thất bạiLưu và đóngBộ nhớ lưu trữ không khả dụngKiểm tra hợp lệ và di chuyển dữ liệu đã lưuBộ nhớ lưu trữ riêngGiới hạn và thời gian chờMã lỗi

Bảo đảm

Hành vi này là một phần của hợp đồng 1.0 và được test của gói bao phủ.

Tình huốngrestate làm gì
Nhiều lần lưu liên tiếpChạy tuần tự theo từng store; lần lưu đang xếp hàng ghi giá trị mới nhất.
Bản ghi không tải đượcautoSave và lưu hàng loạt bỏ qua nó với LOAD_FAILED; chỉ save() tường minh mới thay thế nó.
Component unmount trong lúc lưuLần lưu được yêu cầu vẫn hoàn tất; những lần ghi sau đó vào store đã hủy bị bỏ qua.
Bộ nhớ lưu trữ không khả dụngStore chạy trong bộ nhớ, status().available là false và việc lưu bị từ chối.
Adapter bị treoThao tác hết thời gian sau operationTimeoutMs, và công việc sau đó chờ adapter hoàn tất.
Quá nhiều việc đang chờThao tác mới bị từ chối với QUEUE_FULL thay vì tăng lên không giới hạn.

Lưu tuần tự

Các thao tác của một store không bao giờ chồng lên nhau. Lần lưu bắt đầu khi lần khác đang chờ sẽ lấy giá trị mới nhất, nên lưu ở mỗi thay đổi vẫn ghi trạng thái cuối mà không làm đầy hàng đợi.

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

Thử ngay

Làm chậm bộ nhớ lưu trữ, khiến việc ghi thất bại hoặc bỏ hẳn bộ nhớ lưu trữ.

Đang chuẩn bị ví dụ…

Khi tải thất bại

restateManager.ready bị từ chối với BULK_OPERATION_FAILED và liệt kê mọi store bị lỗi. Cho đến khi bản ghi đó được tải, autoSave và saveAll không thay thế nó và báo LOAD_FAILED.

Thử lại bằng initialize() để giữ thay đổi rồi lưu chúng, gọi restore() để bỏ chúng, hoặc save() để cố ý ghi đè bản ghi.

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

Lưu và đóng

Lần lưu được yêu cầu trước khi unmount vẫn hoàn tất, nên handler "Lưu và đóng" không cần chờ.

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

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

Bộ nhớ lưu trữ không khả dụng

Render phía máy chủ và bộ nhớ lưu trữ bị trình duyệt chặn không phải lỗi khởi động. Kiểm tra available để báo cho người dùng rằng thay đổi chỉ nằm trong bộ nhớ.

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

Kiểm tra hợp lệ và di chuyển dữ liệu đã lưu

version, migrate và validate bảo vệ bạn khỏi bản ghi cũ hoặc hỏng. validate chạy trước khi lưu và sau khi khôi phục hoặc di chuyển.

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

Bộ nhớ lưu trữ riêng

Bất kỳ đối tượng nào có getItem, setItem và removeItem đều dùng được. Các phương thức có thể trả về giá trị hoặc Promise; isAvailable là tùy chọn.

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

Giới hạn và thời gian chờ

Đặt thời gian tối đa cho một thao tác, số lượng được phép chờ và độ lớn tối đa của một giá trị.

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

Mã lỗi

Lỗi do restate tạo có name là RestateError, có code, và với store được lưu có key. Adapter lưu trữ và callback của bạn có thể từ chối bằng lỗi riêng.

MãÝ nghĩa
BULK_OPERATION_FAILEDMột lời gọi hàng loạt như restateManager.ready hoặc saveAll gặp lỗi; xem error.failures.
INDEXEDDB_ABORTEDGiao dịch IndexedDB bị hủy.
INDEXEDDB_BLOCKEDViệc mở cơ sở dữ liệu bị một kết nối ở tab khác chặn.
INDEXEDDB_CONNECTION_CLOSINGKết nối cơ sở dữ liệu đang đóng khi yêu cầu bắt đầu.
INDEXEDDB_OPEN_FAILEDKhông mở được cơ sở dữ liệu.
INDEXEDDB_REQUEST_FAILEDYêu cầu IndexedDB thất bại.
INDEXEDDB_STORE_MISSINGCơ sở dữ liệu đã tồn tại nhưng thiếu object store.
INVALID_STORAGE_RECORDBản ghi đã lưu không phải bản ghi restate hợp lệ.
INVALID_STORED_VALUEGiá trị không qua được validate.
LIFECYCLE_LIMITUpdater liên tục bắt đầu rồi dừng.
LOAD_FAILEDBản ghi không tải được, nên việc lưu tự động hoặc hàng loạt không thay thế nó.
MMKV_UNAVAILABLEKhông tải được react-native-mmkv.
MULTIPLE_ERRORSNhiều callback thất bại trong một thao tác; xem error.errors.
NOTIFICATION_LIMITCác observer liên tục lên lịch thay đổi trong một vòng lặp.
OBSERVER_ERRORMột listener hoặc callback vòng đời đã ném lỗi.
OPERATION_ABORTEDThao tác lưu trữ đã bị hủy.
QUEUE_FULLCó nhiều thao tác chờ hơn mức maxPendingOperations cho phép.
REENTRANT_SETTERMột updater state cố thay đổi chính store đó trong lúc đang chạy.
SCOPE_DESTROYEDMột scope đã hủy được dùng để tạo store.
SEQUENCE_EXHAUSTEDChuỗi nội bộ đã hết định danh.
STORAGE_BLOCKEDLời gọi adapter trước đó chưa kết thúc sau khi hết thời gian hoặc bị hủy.
STORAGE_TIMEOUTThao tác kéo dài hơn operationTimeoutMs.
STORAGE_UNAVAILABLEKhông dùng được bộ nhớ lưu trữ ở đây; store vẫn tiếp tục chạy trong bộ nhớ.
STORAGE_VALUE_TOO_LARGEGiá trị đã mã hóa vượt quá maxStorageCharacters.
STORAGE_VERSION_MISMATCHBản ghi có phiên bản khác và không hàm migrate nào xử lý được.
STORE_DESTROYEDMột store đã hủy được đăng ký hoặc được yêu cầu dùng bộ nhớ lưu trữ.

Tìm trong tài liệu

Tìm trong tiêu đề, mô tả và nội dung của mọi hướng dẫn.