Architecture
The Mini POS System uses IndexedDB for client-side data persistence. The database provides a simple, promise-based API for managing products and sales records.
Database Configuration
const DB_NAME = 'pos-db';
const DB_VER = 1;
Schema
The database contains two object stores:
Products Store
- Name:
products
- Key Path:
id (auto-increment)
- Indexes: None
- Structure:
{
id: number, // Auto-generated
name: string, // Product name
price: number // Product price
}
Sales Store
- Name:
sales
- Key Path:
id (auto-increment)
- Indexes:
date (for range queries)
- Structure:
{
id: number, // Auto-generated
date: string, // ISO 8601 date string
items: Array, // Array of sale items
total: number // Total sale amount
}
Core Functions
openDB()
Opens a connection to the IndexedDB database. Creates object stores if they don’t exist.
Resolves with the database connection
Implementation:
function openDB() {
return new Promise((resolve, reject) => {
const req = indexedDB.open(DB_NAME, DB_VER);
req.onupgradeneeded = () => {
const db = req.result;
if (!db.objectStoreNames.contains('products')) {
db.createObjectStore('products', { keyPath: 'id', autoIncrement: true });
}
if (!db.objectStoreNames.contains('sales')) {
const store = db.createObjectStore('sales', { keyPath: 'id', autoIncrement: true });
store.createIndex('date', 'date');
}
};
req.onsuccess = () => resolve(req.result);
req.onerror = () => reject(req.error);
});
}
Error Handling:
- Rejects if the database cannot be opened
- Rejects if there are permission issues
- Rejects if IndexedDB is not supported
tx()
Helper function for executing transactions. Simplifies transaction management by handling connection and cleanup.
Name of the object store (‘products’ or ‘sales’)
Transaction mode: ‘readonly’ or ‘readwrite’
Callback function that receives the object store and performs operations
Resolves with the result of the transaction
Implementation:
async function tx(store, mode, fn) {
const db = await openDB();
return new Promise((resolve, reject) => {
const t = db.transaction(store, mode);
const s = t.objectStore(store);
const out = fn(s);
t.oncomplete = () => resolve(out?.result ?? out);
t.onerror = () => reject(t.error);
});
}
Error Handling:
- Rejects if the database connection fails
- Rejects if the transaction fails
- Rejects if the object store doesn’t exist
Connection Management
The database connection is managed automatically:
openDB() is called for each transaction
- IndexedDB returns cached connections when available
- Connections are automatically closed after transactions complete
- Schema upgrades happen automatically on version changes
Usage Pattern
All database operations follow this pattern:
// 1. Import the function
import { getProducts } from './js/db.js';
// 2. Call the async function
const products = await getProducts();
// 3. Handle errors with try/catch
try {
const products = await getProducts();
console.log(products);
} catch (error) {
console.error('Database error:', error);
}