Skip to content

WebDB

پوششی از جنس Promise گرد IndexedDB. IndexedDBِ خام بر فراخوان‌های رویدادی و تراکنش استوار است: هر خواندن یا نوشتن پنج گام دارد (گشودن ← تراکنش ← objectStore ← درخواست ← onsuccess/onerror). WebDB همهٔ آن را در await db.add({ storeName, data }) جمع می‌کند.

API

new WebDB(options)

پارامترتوضیحنوعپیش‌فرض
dbNameنام پایگاه دادهstringالزامی
versionنسخهٔ طرحواره؛ هر بار که stores عوض شد آن را بالا ببریدnumber1
storesانبارهای شیء و نمایه‌ها، به‌شکل اعلانی، که هنگام ارتقا ساخته می‌شوندIDBStoreSchema[][]
upgradeدریچهٔ گریز برای کوچ‌هایی که طرحواره نمی‌تواند بیانشان کند؛ پس از stores می‌دودFunction

هر متد با همان شکل IDBResult برآورده یا رد می‌شود، پس فراخواننده تنها error را وارسی می‌کند.

متدتوضیح
openDataBase()می‌گشاید (و در صورت نیاز ارتقا می‌دهد)
closeDataBase()می‌بندد و دستگیره را رها می‌کند
refreshDatabase()می‌بندد و دوباره می‌گشاید
deleteDatabase()پایگاه داده را پاک می‌کند
add({ storeName, data })درج می‌کند؛ اگر کلید از پیش باشد شکست می‌خورد
update({ storeName, data })put است: درج یا رونویسی
readByKey({ storeName, key })یک رکورد می‌خواند
readAll({ storeName, query?, count? })همهٔ رکوردها را می‌خواند
readByCursor({ storeName, keyRange?, direction? })با مکان‌نما پیمایش می‌کند
count({ storeName, query? })رکوردها را می‌شمارد
delete({ storeName, key })یک رکورد را پاک می‌کند
clear({ storeName })یک انباره را خالی می‌کند

db.collection<T>(name)

دستگیره‌ای نوع‌دار و آسان‌گیر بر یک انباره. نام انباره را یک بار می‌بندد و به‌جای IDBResult مقدارهای ساده برمی‌گرداند.

عضوبازگشتدر صورت شکست
get(key)Promise<T | null>null
all()Promise<T[]>[]
count()Promise<number>0
add(value)Promise<boolean>false
put(value)Promise<boolean>false
remove(key)Promise<boolean>false
clear()Promise<boolean>false
js
const notes = db.collection('books_notes');
await notes.put(note); // اگر شکست بخورد false
const all = await notes.all(); // اگر شکست بخورد []

لایهٔ درست را برگزینید

همهٔ این متدها خطا را می‌بلعند. برای آنچه بیشتر برنامه‌ها در IndexedDB نگه می‌دارند (تا کجا خوانده‌اند، پیش‌نویس‌ها، انباره‌ها) همین پیش‌فرضِ درست است: خواندنِ ناکام باید آن قابلیت را کم‌رنگ کند، نه اینکه صفحه را از پا بیندازد. اما آنجا که خودِ نوشتن همان کنش کاربر است (ذخیرهٔ سند، تکمیل خرید) پیش‌فرض نادرستی است: آنجا متدهای بالا را که IDBResult می‌دهند صدا بزنید و خودتان به شکست رسیدگی کنید.

نمونه

js
import { WebDB } from 'ranuts';

const db = new WebDB({
  dbName: 'read',
  version: 4,
  stores: [
    { name: 'books', options: { keyPath: 'id' }, indexes: [{ name: 'byAuthor', keyPath: 'author' }] },
    { name: 'notes', options: { keyPath: 'id' } },
  ],
});

await db.openDataBase();
await db.add({ storeName: 'books', data: { id: '1', title: 'Walden' } });
const { data } = await db.readByKey({ storeName: 'books', key: '1' });

یادداشت‌ها

  1. انباره‌ها را تنها درون تراکنش ارتقا می‌توان ساخت: به همین سبب از پیش اعلام می‌شوند، نه اینکه پس از گشوده شدن پایگاه داده ساخته شوند. ساختن انباره یا نمایهٔ نبوده، هرچند بار هم انجام شود نتیجه یکی است، پس نگه داشتن همان آرایهٔ stores در نسخه‌های گوناگون بی‌خطر است.
  2. پایین آمدن نسخه خودش را درمان می‌کند. گشودن با نسخه‌ای کمتر از آنچه روی دیسک است VersionError می‌دهد؛ WebDB نسخهٔ واقعی را از دل همان بیرون می‌کشد، خود را هم‌تراز می‌کند و دوباره می‌گشاید، به‌جای آنکه خطا را آشکار کند.
  3. این اتصال هرگز جلوی ارتقا را نمی‌گیرد. هر گشودن onversionchange را ثبت می‌کند، پس وقتی زبانه یا کارگری دیگر نسخهٔ بالاتری بخواهد، این اتصال خودش را می‌بندد.
  4. آن را با singleFlight جفت کنید تا فراخوانندگان هم‌زمان یک گشودن را شریک شوند: const ready = singleFlight(() => db.openDataBase()).

منتشرشده تحت مجوز MIT.