টাইপস্ক্রিপ্ট এবং ইনডেক্সডডিবি
এই প্রবন্ধটি টাইপস্ক্রিপ্ট এবং ইনডেক্সডডিবি নিয়ে আলোচনা করে।
আমরা টাইপস্ক্রিপ্ট এবং ইনডেক্সডডিবি ব্যবহারিক উদাহরণের মাধ্যমে ব্যাখ্যা করবো।
YouTube Video
টাইপস্ক্রিপ্ট এবং ইনডেক্সডডিবি
ইনডেক্সডডিবি হলো একটি লো-লেভেল নোএসকিউএল স্টোরেজ, যা ব্রাউজারে স্ট্রাকচার ডেটা সংরক্ষণ করতে দেয়। টাইপস্ক্রিপ্ট ব্যবহার করে আপনি স্কিমা টাইপ-নিরাপদ (type-safe) ভাবে প্রকাশ করতে পারেন, যা ভুল কমায় এবং রক্ষণাবেক্ষণ সহজ করে।
মৌলিক শব্দতত্ত্ব এবং কার্যপ্রবাহ
IndexedDB হলো ব্রাউজারের ভিতরে থাকা একটি ছোট ডেটাবেস। এটি ডেটা পরিচালনা করে বিভিন্ন ব্যবস্থার মাধ্যমে, যেমন নাম ও ভার্সন সহ ডেটাবেস, অবজেক্ট স্টোর, লেনদেন (ট্রানজ্যাকশন), সূচক (ইনডেক্স) এবং কার্সর। ডেটাবেসের ভার্সন থাকে এবং যখন ভার্সন আপগ্রেড করা হয়, তখন স্কিমা আপডেট করার জন্য onupgradeneeded কল করা হয়, যেমন টেবিল তৈরি বা পরিবর্তন করা।
ইনডেক্সডডিবি খোলা (মৌলিক প্যাটার্ন)
প্রথমে, আমরা দেখাবো কীভাবে ইনডেক্সডডিবি দিয়ে ডেটাবেস খোলা যায় এবং প্রয়োজনে onupgradeneeded ইভেন্টে একটি অবজেক্ট স্টোর তৈরী করা হয়।
1// Open an IndexedDB database and create an object store if needed.
2// This code shows the classic callback-based IndexedDB API wrapped into a Promise.
3function openDatabase(dbName: string, version: number): Promise<IDBDatabase> {
4 return new Promise((resolve, reject) => {
5 const request = indexedDB.open(dbName, version);
6
7 request.onerror = () => {
8 reject(request.error);
9 };
10
11 request.onupgradeneeded = (event) => {
12 const db = request.result;
13 if (!db.objectStoreNames.contains('todos')) {
14 // Create object store with keyPath 'id'
15 db.createObjectStore('todos', { keyPath: 'id' });
16 }
17 };
18
19 request.onsuccess = () => {
20 resolve(request.result);
21 };
22 });
23}
24
25// Usage example:
26openDatabase('my-db', 1)
27 .then(db => {
28 console.log('DB opened', db.name, db.version);
29 db.close();
30 })
31 .catch(err => console.error('Failed to open DB', err));- এই কোডটি ডেটাবেস খুলে এবং সফল বা ব্যর্থ হয়েছে কিনা তা লগ করে।
- প্রয়োজনে,
onupgradeneededইভেন্টেtodosস্টোর তৈরি করা হয়।
টাইপস্ক্রিপ্টে টাইপ সংজ্ঞায়িতকরণ (মডেলসমূহ)
এরপর আমরা টাইপস্ক্রিপ্ট ব্যবহার করে ডেটা টাইপ নির্ধারণ করবো। এটি পরবর্তী CRUD অপারেশনগুলোতে টাইপ নিরাপত্তা নিশ্চিত করে।
1// Define the TypeScript interface for a Todo item.
2// This helps with type safety in the database operations.
3interface Todo {
4 id: string; // primary key
5 title: string;
6 completed: boolean;
7 createdAt: number;
8}- এখানে, আমরা
Todoটাইপটি সংজ্ঞায়িত করছি।
সরল CRUD ফাংশনের বাস্তবায়নের উদাহরণ
পরবর্তী ধাপে, আমরা অবজেক্ট স্টোর থেকে সংযোজন, অনুসন্ধান, আপডেট এবং মুছার মূল CRUD অপারেশনগুলোর উদাহরণ দেখাবো। প্রত্যেকটি ফাংশন একটি IDBDatabase নেয় এবং একটি Promise রিটার্ন করে।
1// CRUD utilities for the 'todos' object store.
2// Each operation uses a transaction and returns a Promise for easier async/await usage.
3
4function addTodo(db: IDBDatabase, todo: Todo): Promise<void> {
5 return new Promise((resolve, reject) => {
6 const tx = db.transaction('todos', 'readwrite');
7 const store = tx.objectStore('todos');
8 const req = store.add(todo);
9
10 req.onsuccess = () => {
11 console.log('Todo added', todo.id);
12 };
13 req.onerror = () => reject(req.error);
14
15 tx.oncomplete = () => resolve();
16 tx.onerror = () => reject(tx.error);
17 });
18}- এই ফাংশনটি IndexedDB-র
todosস্টোরে একটি নতুনTodoযোগ করে। এটি অ্যাসিনক্রোনাস প্রসেসিংয়ের জন্য একটি Promise রিটার্ন করে, যা সম্পন্ন হলে resolve হয়।
1function getTodo(db: IDBDatabase, id: string): Promise<Todo | undefined> {
2 return new Promise((resolve, reject) => {
3 const tx = db.transaction('todos', 'readonly');
4 const store = tx.objectStore('todos');
5 const req = store.get(id);
6
7 req.onsuccess = () => resolve(req.result as Todo | undefined);
8 req.onerror = () => reject(req.error);
9 });
10}- এই ফাংশনটি নির্দিষ্ট আইডি সহ
Todoখুঁজে এনে, পাওয়া গেলে অবজেক্টটি রিটার্ন করে। কোন মিল পাওয়া না গেলে, এটিundefinedরিটার্ন করে।
1function updateTodo(db: IDBDatabase, todo: Todo): Promise<void> {
2 return new Promise((resolve, reject) => {
3 const tx = db.transaction('todos', 'readwrite');
4 const store = tx.objectStore('todos');
5 const req = store.put(todo);
6
7 req.onsuccess = () => {
8 console.log('Todo updated', todo.id);
9 };
10 req.onerror = () => reject(req.error);
11
12 tx.oncomplete = () => resolve();
13 tx.onerror = () => reject(tx.error);
14 });
15}- এই ফাংশনটি বর্তমান
Todoডেটা আপডেট করে। সাফল্যের ক্ষেত্রে, আপডেট হওয়াTodo-র আইডি লগ করা হয়।
1function deleteTodo(db: IDBDatabase, id: string): Promise<void> {
2 return new Promise((resolve, reject) => {
3 const tx = db.transaction('todos', 'readwrite');
4 const store = tx.objectStore('todos');
5 const req = store.delete(id);
6
7 req.onsuccess = () => {
8 console.log('Todo deleted', id);
9 };
10 req.onerror = () => reject(req.error);
11
12 tx.oncomplete = () => resolve();
13 tx.onerror = () => reject(tx.error);
14 });
15}-
এই ফাংশনটি নির্দিষ্ট আইডি সহ
Todo-টি মুছে ফেলে। প্রসেসিং সফল হলে ডিলিট হওয়া ID কনসোলে লেখে। -
এই ফাংশনগুলো লেনদেন সফলভাবে সম্পন্ন হলে বা ত্রুটি হলে প্রমিস পূর্ণ (resolve) বা বাতিল (reject) করে।
console.logব্যবহার করে আউটপুট দেখা এক্সিকিউশনের সময় কী ঘটছে তা সহজে ট্র্যাক করতে সহায়তা করে।
ইনডেক্স ও যৌগিক কুয়েরী
ইনডেক্সডডিবিতে ইনডেক্স ব্যবহার করে নির্দিষ্ট ফিল্ডে দ্রুত অনুসন্ধান করা যায়। এখানে আমরা createdAt ফিল্ডে একটি ইনডেক্স তৈরি করেছি এবং একটি রেঞ্জ কুয়েরির উদাহরণ দেখিয়েছি।
1// When opening DB, create an index for createdAt.
2// Then demonstrate a range query using the index.
3
4function openDatabaseWithIndex(dbName: string, version: number): Promise<IDBDatabase> {
5 return new Promise((resolve, reject) => {
6 const request = indexedDB.open(dbName, version);
7
8 request.onupgradeneeded = () => {
9 const db = request.result;
10 if (!db.objectStoreNames.contains('todos')) {
11 const store = db.createObjectStore('todos', { keyPath: 'id' });
12 // Create an index on createdAt for sorting/filtering
13 store.createIndex('by-createdAt', 'createdAt', { unique: false });
14 } else {
15 const store = request.transaction!.objectStore('todos');
16 if (!store.indexNames.contains('by-createdAt')) {
17 store.createIndex('by-createdAt', 'createdAt', { unique: false });
18 }
19 }
20 };
21
22 request.onerror = () => reject(request.error);
23 request.onsuccess = () => resolve(request.result);
24 });
25}- এই ফাংশনটি ডেটাবেস খোলে এবং
createdAtফিল্ডেby-createdAtইনডেক্স তৈরি বা যাচাই করে। এর ফলে creation date অনুসারে দ্রুত অনুসন্ধান ও সাজানো সম্ভব।
1async function getTodosCreatedAfter(db: IDBDatabase, timestamp: number): Promise<Todo[]> {
2 return new Promise((resolve, reject) => {
3 const tx = db.transaction('todos', 'readonly');
4 const store = tx.objectStore('todos');
5 const index = store.index('by-createdAt');
6 const range = IDBKeyRange.lowerBound(timestamp, true); // exclusive
7 const req = index.openCursor(range);
8
9 const results: Todo[] = [];
10 req.onsuccess = (event) => {
11 const cursor = (event.target as IDBRequest).result as IDBCursorWithValue | null;
12 if (cursor) {
13 results.push(cursor.value as Todo);
14 cursor.continue();
15 } else {
16 resolve(results);
17 }
18 };
19 req.onerror = () => reject(req.error);
20 });
21}-
এই ফাংশনটি কেবল নির্দিষ্ট টাইমস্ট্যাম্পের পরে তৈরি হওয়া
Todo-গুলো বের করে। ইনডেক্স ব্যবহারে creation date এর ক্রম অনুসারে দ্রুত ডেটা স্ক্যান করা যায়। -
এই উদাহরণে, ডেটাবেস আপগ্রেডের সময় একটি
by-createdAtইনডেক্স তৈরি হয় এবং নির্দিষ্ট সময়ের পরে তৈরি হওয়াTodoআইটেমগুলো কার্সরের মাধ্যমে গোনা হয়।
Promise-ভিত্তিক হালকা Wrapper
লো-লেভেল IndexedDB API লেখা জটিল, এবং একাধিক একই রকম অপারেশন পুনরাবৃত্তি হলে অপ্রয়োজনীয়তা ও বাগের সৃষ্টি হতে পারে। অতএব, অপারেশনগুলো অ্যাবস্ট্রাক্ট করে এমন একটি সাধারণ টাইপস্ক্রিপ্ট র্যাপার ক্লাস প্রস্তুত করার মাধ্যমে আমরা কোডের সরলতা ও রক্ষণাবেক্ষণযোগ্যতা বৃদ্ধি করি। নিচে মৌলিক ফিচারের ওপর ভিত্তি করে একটি বাস্তবায়ন দেয়া হলো।
1// A minimal TypeScript wrapper around IndexedDB to simplify common operations.
2// This class is generic over the store's value type and assumes 'keyPath' is 'id'.
3
4class IDBWrapper<T extends { id: string }> {
5 private dbPromise: Promise<IDBDatabase>;
6
7 constructor(private dbName: string, private version: number, private storeName: string) {
8 this.dbPromise = this.open();
9 }- এই ক্লাস ইনডেক্সডডিবির প্রয়োজনীয় অপারেশন নিয়ে টাইপ-নিরাপদ CRUD ফাংশন সরবরাহ করে। এটি ধরে নেয় অবজেক্ট স্টোরের কী হলো
id।
1 private open(): Promise<IDBDatabase> {
2 return new Promise((resolve, reject) => {
3 const req = indexedDB.open(this.dbName, this.version);
4 req.onerror = () => reject(req.error);
5 req.onupgradeneeded = () => {
6 const db = req.result;
7 if (!db.objectStoreNames.contains(this.storeName)) {
8 db.createObjectStore(this.storeName, { keyPath: 'id' });
9 }
10 };
11 req.onsuccess = () => resolve(req.result);
12 });
13 }- এটি ডেটাবেস খুলে এবং প্রয়োজনে নতুন অবজেক্ট স্টোর তৈরী করে। স্টোর ইনিশিয়ালাইজেশন
upgradeইভেন্টের মাধ্যমে হয়।
1 async add(item: T): Promise<void> {
2 const db = await this.dbPromise;
3 await new Promise<void>((resolve, reject) => {
4 const tx = db.transaction(this.storeName, 'readwrite');
5 const store = tx.objectStore(this.storeName);
6 const req = store.add(item);
7 req.onsuccess = () => {
8 console.log('added', item.id);
9 };
10 req.onerror = () => reject(req.error);
11 tx.oncomplete = () => resolve();
12 tx.onerror = () => reject(tx.error);
13 });
14 }- ডেটা ইনডেক্সডডিবি স্টোরে সংযোজন করে। সংযোজনের পর আইডি কনসোলে দেখায়।
1 async get(id: string): Promise<T | undefined> {
2 const db = await this.dbPromise;
3 return new Promise((resolve, reject) => {
4 const tx = db.transaction(this.storeName, 'readonly');
5 const store = tx.objectStore(this.storeName);
6 const req = store.get(id);
7 req.onsuccess = () => resolve(req.result as T | undefined);
8 req.onerror = () => reject(req.error);
9 });
10 }- নির্দিষ্ট আইডির সঙ্গে সংশ্লিষ্ট ডেটা বের করে আনে। ডেটা না থাকলে
undefinedফেরত দেয়।
1 async put(item: T): Promise<void> {
2 const db = await this.dbPromise;
3 return new Promise((resolve, reject) => {
4 const tx = db.transaction(this.storeName, 'readwrite');
5 const store = tx.objectStore(this.storeName);
6 const req = store.put(item);
7 req.onsuccess = () => {
8 console.log('put', item.id);
9 };
10 req.onerror = () => reject(req.error);
11 tx.oncomplete = () => resolve();
12 tx.onerror = () => reject(tx.error);
13 });
14 }- বিদ্যমান ডেটা আপডেট বা নতুন ডেটা সংযোজন করে। প্রসেসিংয়ের পর আপডেটকৃত আইডি কনসোলে দেখায়।
1 async delete(id: string): Promise<void> {
2 const db = await this.dbPromise;
3 return new Promise((resolve, reject) => {
4 const tx = db.transaction(this.storeName, 'readwrite');
5 const store = tx.objectStore(this.storeName);
6 const req = store.delete(id);
7 req.onsuccess = () => {
8 console.log('deleted', id);
9 };
10 req.onerror = () => reject(req.error);
11 tx.oncomplete = () => resolve();
12 tx.onerror = () => reject(tx.error);
13 });
14 }- নির্দিষ্ট আইডির ডেটা মুছে ফেলে। সফল হলে, ডিলিট হওয়া আইডি কনসোলে দেখায়।
1 async getAll(): Promise<T[]> {
2 const db = await this.dbPromise;
3 return new Promise((resolve, reject) => {
4 const tx = db.transaction(this.storeName, 'readonly');
5 const store = tx.objectStore(this.storeName);
6 const req = store.getAll();
7 req.onsuccess = () => resolve(req.result as T[]);
8 req.onerror = () => reject(req.error);
9 });
10 }
11}- স্টোরের সকল ডেটা বের করে আনে। ফেরত দেয়া মানটি হলো
Tটাইপের অ্যারে।
1// Example usage with Todo type:
2interface Todo {
3 id: string;
4 title: string;
5 completed: boolean;
6 createdAt: number;
7}
8
9const todoStore = new IDBWrapper<Todo>('my-db', 1, 'todos');
10
11(async () => {
12 const newTodo: Todo = { id: '1', title: 'Learn IndexedDB', completed: false, createdAt: Date.now() };
13 await todoStore.add(newTodo);
14 const fetched = await todoStore.get('1');
15 console.log('fetched', fetched);
16 newTodo.completed = true;
17 await todoStore.put(newTodo);
18 const all = await todoStore.getAll();
19 console.log('all todos', all);
20 await todoStore.delete('1');
21})();-
এই কোডটি
IDBWrapperক্লাসের বাস্তব ব্যবহারের একটি উদাহরণ। এতেTodoডেটা যোগ, অনুসন্ধান, আপডেট, তালিকাভুক্ত এবং মুছে ফেলার প্রক্রিয়া প্রদর্শিত হয়েছে। -
এই wrapper টি সহজে মৌলিক CRUD অপারেশন পরিচালনা করতে দেয়। বাস্তব পরিবেশে, আপনাকে ত্রুটি ব্যবস্থাপনা ও স্কিমা ব্যবস্থাপনাও (ইনডেক্স) পরিচালনা করতে হবে।
স্কিমা মাইগ্রেশন (ভার্সন আপগ্রেড)
ডাটাবেস স্কিমা পরিবর্তন করতে, indexedDB.open-এর দ্বিতীয় আর্গুমেন্ট (ভার্সন) বাড়ান এবং onupgradeneeded-এ সেটি আপডেট করুন। আপনাকে এমনভাবে ডিজাইন করতে হবে যাতে বিদ্যমান লেনদেন শেষ হয় এবং ক্ষতিকর পরিবর্তনগুলো এড়ানো যায়।
1// Example of handling upgrade to version 2: add an index and perhaps migrate data.
2// onupgradeneeded receives an event where oldVersion and newVersion are accessible.
3
4function upgradeToV2(dbName: string): Promise<IDBDatabase> {
5 return new Promise((resolve, reject) => {
6 const req = indexedDB.open(dbName, 2);
7 req.onupgradeneeded = (ev) => {
8 const db = req.result;
9 const oldVersion = (ev as IDBVersionChangeEvent).oldVersion;
10 console.log('Upgrading DB from', oldVersion, 'to', db.version);
11 let store: IDBObjectStore;
12 if (!db.objectStoreNames.contains('todos')) {
13 store = db.createObjectStore('todos', { keyPath: 'id' });
14 } else {
15 store = req.transaction!.objectStore('todos');
16 }
17 // Add index if not present
18 if (!store.indexNames.contains('by-completed')) {
19 store.createIndex('by-completed', 'completed', { unique: false });
20 }
21
22 // Optional: data migration logic if necessary can go here,
23 // but heavy migrations often should be done lazily on read.
24 };
25 req.onsuccess = () => resolve(req.result);
26 req.onerror = () => reject(req.error);
27 });
28}onupgradeneeded-এর ভেতরে ভারী প্রসেসিং UI ব্লক করতে পারে, তাই সেটা কম রাখুন এবং সম্ভব হলে মাইগ্রেশন বিলম্বিত করুন (অ্যাপ-শুরুর সময় ধাপে ধাপে প্রসেসিং)।
ট্রানজেকশন সম্পর্কে সতর্কতা (লাইফসাইকেল এবং ত্রুটি)
যে স্ক্রিপ্ট ট্রানজেকশন তৈরি করেছে তার এক্সিকিউশন শেষ হওয়ার আগেই স্বয়ংক্রিয়ভাবে ট্রানজেকশন কমিট হয়ে যায়। একই ট্রানজেকশনের মধ্যে অনেকগুলো অ্যাসিনক্রোনাস অপারেশন চালানো হলে, await ব্যবহারে এটি অপ্রত্যাশিতভাবে কমিট হয়ে যেতে পারে; সতর্ক থাকুন।
1// Bad pattern: awaiting outside transaction callbacks can cause tx to auto-commit.
2// Good pattern is to chain requests and resolve on tx.oncomplete as shown earlier.
3
4// Example: Do multiple operations inside single tx, avoid awaiting inside.
5function multiOperation(db: IDBDatabase, items: Todo[]): Promise<void> {
6 return new Promise((resolve, reject) => {
7 const tx = db.transaction('todos', 'readwrite');
8 const store = tx.objectStore('todos');
9
10 for (const item of items) {
11 const req = store.put(item);
12 req.onerror = () => console.error('put error', req.error);
13 // Do NOT await here; just schedule requests synchronously.
14 }
15
16 tx.oncomplete = () => {
17 console.log('All operations in transaction completed');
18 resolve();
19 };
20 tx.onerror = () => reject(tx.error);
21 });
22}- ট্রানজেকশনের লাইফস্প্যান সম্পর্কে সচেতন থাকুন; প্রয়োজন হলে আলাদা ট্রানজেকশন ব্যবহার করুন, বা অপারেশনগুলো ট্রানজেকশনের ভেতরে সিঙ্ক্রোনাসলি সম্পন্ন করুন।
কার্সর অ্যাপ্লিকেশন এবং পেজিনেশন
কার্সর ব্যবহার করে আপনি বৃহৎ পরিসরের ডেটা ক্রমানুসারে প্রক্রিয়া করতে পারেন অথবা অফসেট ব্যবহার না করে সহজ পেজিনেশন কার্যকর করতে পারেন।
1// Example: fetch first N items using a cursor (ascending by key).
2function fetchFirstN(db: IDBDatabase, n: number): Promise<Todo[]> {
3 return new Promise((resolve, reject) => {
4 const tx = db.transaction('todos', 'readonly');
5 const store = tx.objectStore('todos');
6 const req = store.openCursor();
7 const out: Todo[] = [];
8 req.onsuccess = (ev) => {
9 const cursor = (ev.target as IDBRequest).result as IDBCursorWithValue | null;
10 if (cursor && out.length < n) {
11 out.push(cursor.value as Todo);
12 cursor.continue();
13 } else {
14 resolve(out);
15 }
16 };
17 req.onerror = () => reject(req.error);
18 });
19}- কার্সর দিয়ে একের পর এক আইটেম এনে মেমোরি ব্যবহার কমানো সম্ভব। পেজিং প্রয়োগে, শেষ পড়া কী মনে রাখা সাধারণ চর্চা।
ত্রুটি নিয়ন্ত্রণ ও বিকল্প ব্যবস্থা
1// Feature detection
2if (!('indexedDB' in window)) {
3 console.warn('IndexedDB is not supported. Falling back to localStorage.');
4 // implement fallback logic...
5}- ব্রাউজারের ইমপ্লিমেন্টেশন পার্থক্য অথবা ব্যবহারকারীর প্রাইভেসি সেটিংস, যেমন প্রাইভেট ব্রাউজিং-এর কারণে IndexedDB কখনও কখনও ব্যবহারযোগ্য নাও হতে পারে। অতএব, নিশ্চিত করুন
indexedDBবিদ্যমান কি না এবং যদি না থাকে তবেlocalStorageএর মত বিকল্প ব্যবস্থা দিন।
পারফরম্যান্স ও সেরা চর্চা
IndexedDB দ্রুত এবং শক্তিশালী, তবে পারফরম্যান্স এর ডিজাইন ও ডেটা ব্যবস্থাপনার ওপর অনেকটাই নির্ভর করে পরিবর্তিত হতে পারে। ব্যবহারের ধরন অনুযায়ী নিম্নোক্তভাবে অপ্টিমাইজেশন করা যেতে পারে:।
- বাস্তব ব্যবহারের ভিত্তিতে অবজেক্ট স্টোর ডিজাইন করুন। যেমন, পড়া বেশি হলে ইনডেক্স দিন; লেখা বেশি হলে কির ডিজাইন সরল রাখুন।
- ছবি ও অডিওর মতো বড় বাইনারি ডেটা Blob হিসেবে সংরক্ষণ করা উচিত, অথবা প্রয়োজনে File API বা সার্ভিস ওয়ার্কার ব্যবহারে নিয়ন্ত্রণ করুন। প্রয়োজনে কম্প্রেশনও বিবেচনা করা যেতে পারে।
- লেনদেন যতটা সম্ভব সংক্ষিপ্ত রাখুন এবং বড় প্রসেসিং লেনদেনের বাইরে করুন যাতে লক সময় কম হয়।
- ইনডেক্স অনুসন্ধান দ্রুত করতে পারে, কিন্তু ইনসার্ট ও আপডেট ধীর করে, তাই শুধুমাত্র প্রয়োজনীয় ইনডেক্স তৈরি করুন।
- অনেক ছোট ছোট ডেটা নিয়ে কাজ করার সময়, একবারে
getAll()দিয়ে সব উঠালে মেমরি শেষ হয়ে যেতে পারে। কার্সর ব্যবহার করে প্রসেস ভাগ করলে মেমরি ব্যবহার কমানো যায়।
নিরাপত্তা ও গোপনীয়তা
Same-origin নীতিমতে, IndexedDB ডেটা আলাদা ডোমেইন ও প্রোটোকলের জন্য আলাদা থাকে। ব্যবহারকারীরা যদি ব্রাউজারের ডেটা মুছে ফেলে বা প্রাইভেট মোড ব্যবহার করে, তাহলে ডেটা হারানোর সম্ভাবনা থাকবে ধরে নিয়ে ডিজাইন করুন।
সারসংক্ষেপ এবং সুপারিশকৃত ডিজাইন প্যাটার্ন
TypeScript এর সঙ্গে IndexedDB কার্যকরভাবে ব্যবহার করতে টাইপ ও অ্যাসিঙ্ক্রোনাস প্রসেস তৈরির পাশাপাশি ভার্সন ব্যবস্থাপনা ও লেনদেন ডিজাইনের প্রতি সচেতন থাকা এবং সাধারণ প্রসেস ওর্যাপ করে রক্ষণাবেক্ষণ সহজ করা গুরুত্বপূর্ণ।
- টাইপস্ক্রিপ্টে টাইপ সংজ্ঞায়িত এবং IndexedDB অপারেশন Promise/async/await দ্বারা মোড়ানো কোডের নিরাপত্তা এবং পাঠযোগ্যতা বাড়ায়।
- স্কিমা পরিবর্তনে
onupgradeneededসহ ভার্সন ম্যানেজমেন্ট ব্যবহার করা উচিত এবং ভারী প্রসেসিং যথাসম্ভব বিলম্বিত রাখা উচিত। - ট্রানজেকশন সংক্ষেপে রাখুন এবং একই ট্রানজেকশনের মধ্যে ভারী অ্যাসিনক্রোনাস প্রসেসিং এড়িয়ে চলুন।
- ওর্যাপার ক্লাস তৈরি করলে ত্রুটি ব্যবস্থাপনা, লগিং এবং টাইপ সংজ্ঞার মতো পুনরাবৃত্ত সাধারণ প্রসেস কমানো যায়।
আপনি আমাদের ইউটিউব চ্যানেলে ভিজ্যুয়াল স্টুডিও কোড ব্যবহার করে উপরের নিবন্ধটি অনুসরণ করতে পারেন। দয়া করে ইউটিউব চ্যানেলটিও দেখুন।