restate / v1.0.0
אמינות by design
מה restate מבטיח כשהאחסון איטי, נכשל או חסר, ואיך לקרוא את השגיאות שהוא מדווח.
בעמוד הזה
ההתחייבויותשמירות מסודרותנסו את זהכשהטעינה נכשלתשמירה וסגירהאין אחסון זמיןאימות והגירה של נתונים שמוריםאחסון משלכםמגבלות וזמני תפוגהקודי שגיאהההתחייבויות
ההתנהגויות האלה הן חלק מהחוזה של 1.0 ומכוסות בבדיקות של החבילה.
| מצב | מה restate עושה |
|---|---|
כמה שמירות ברצף | מריץ אותן לפי הסדר לכל מאגר; שמירה בתור כותבת את הערך העדכני. |
רשומה לא נטענה | autoSave ושמירות גורפות מדלגים עליה עם LOAD_FAILED; רק save() מפורש מחליף אותה. |
הרכיב מוסר באמצע שמירה | השמירה שהתבקשה מסתיימת; כתיבות מאוחרות יותר למאגר שהושמד נזנחות. |
האחסון לא זמין | המאגר עובד בזיכרון, status().available הוא false, ושמירות נדחות. |
מתאם נתקע | לפעולה נגמר הזמן אחרי operationTimeoutMs, והעבודה הבאה ממתינה עד שהמתאם מסיים. |
יותר מדי עבודה ממתינה | פעולות חדשות נדחות עם QUEUE_FULL במקום לגדול בלי גבול. |
שמירות מסודרות
פעולות של מאגר אחד לעולם לא חופפות. שמירה שמתחילה בזמן שאחרת ממתינה לוקחת את הערך החדש ביותר, כך ששמירה בכל שינוי כותבת את המצב האחרון בלי למלא את התור.
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 ומפרט כל מאגר שנכשל. עד שהרשומה הזו נטענת, autoSave ו־saveAll לא מחליפים אותה ומדווחים LOAD_FAILED.
נסו שוב עם initialize() כדי לשמור את העריכות ולשמור אותן, קראו ל־restore() כדי לזרוק אותן, או ל־save() כדי לדרוס את הרשומה בכוונה.
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);
}
}שמירה וסגירה
שמירה שהתבקשה לפני ההסרה מסתיימת בכל זאת, כך שמטפל «שמירה וסגירה» לא צריך להמתין.
function Document({ onClose }) {
const useDraft = useRestateScope((scope) => persistedRestate('', { scope, key: 'draft' }));
const saveAndClose = () => {
useDraft.save(); // finishes even after this component unmounts
onClose();
};
// …
}אימות והגירה של נתונים שמורים
version, migrate ו־validate מגנים עליכם מרשומות ישנות או פגומות. validate רץ לפני שמירה ואחרי שחזור או הגירה.
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 אופציונלי.
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,
},
);מגבלות וזמני תפוגה
כווננו כמה זמן פעולה יכולה להימשך, כמה פעולות יכולות להמתין וכמה גדול ערך יכול להיות.
persistedRestate(value, {
key: 'draft',
operationTimeoutMs: 10_000, // default 30000
maxPendingOperations: 64, // default 256
maxStorageCharacters: 1_000_000,
});קודי שגיאה
לשגיאות ש־restate יוצר יש name בשם RestateError, code, ולמאגרים שמורים גם key. מתאמי אחסון וה־callbacks שלכם יכולים לדחות עם שגיאות משלהם.
| קוד | משמעות |
|---|---|
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_LIMIT | updater המשיך להתחיל ולהיעצר שוב ושוב. |
LOAD_FAILED | לא ניתן היה לטעון רשומה, ולכן שמירה אוטומטית או גורפת לא החליפה אותה. |
MMKV_UNAVAILABLE | לא ניתן לטעון את react-native-mmkv. |
MULTIPLE_ERRORS | כמה callbacks נכשלו בפעולה אחת; ראו error.errors. |
NOTIFICATION_LIMIT | צופים המשיכו לתזמן שינויים בלולאה. |
OBSERVER_ERROR | מאזין או callback של מחזור חיים זרק שגיאה. |
OPERATION_ABORTED | פעולת אחסון בוטלה. |
QUEUE_FULL | המתינו יותר פעולות ממה ש־maxPendingOperations מאפשר. |
REENTRANT_SETTER | updater של מצב ניסה לשנות את אותו מאגר בזמן שרץ. |
SCOPE_DESTROYED | נעשה שימוש ב־scope שהושמד כדי ליצור מאגרים. |
SEQUENCE_EXHAUSTED | לרצף פנימי נגמרו המזהים. |
STORAGE_BLOCKED | קריאה קודמת למתאם לא הסתיימה אחרי תפוגת זמן או ביטול. |
STORAGE_TIMEOUT | פעולה נמשכה יותר מ־operationTimeoutMs. |
STORAGE_UNAVAILABLE | כאן אי אפשר להשתמש באחסון; המאגר ממשיך לעבוד בזיכרון. |
STORAGE_VALUE_TOO_LARGE | הערך המקודד חורג מ־maxStorageCharacters. |
STORAGE_VERSION_MISMATCH | לרשומה יש גרסה אחרת ואין פונקציית migrate שמטפלת בה. |
STORE_DESTROYED | נרשמו למאגר שהושמד או ביקשו ממנו להשתמש באחסון. |