UNPKG

local-fake-api

Version:

A simple async local mock API without backend.

143 lines (142 loc) 5.56 kB
// src/fakeApi/createIndexedDbApi.ts import { delay, getUuid } from "../utils"; import { db } from "./indexedDb"; export function createIndexedDbApi(tableName, primaryKey) { // _primaryKey always exists const _primaryKey = (primaryKey || "id"); // Helper to filter items by key-value pairs async function filterItems(items, filter) { if (!filter) return items; return items.filter((item) => Object.entries(filter).every(([k, v]) => item[k] === v)); } // List (ProTable-friendly) async function list(filter) { try { await delay(100); const table = await db.getTable(tableName, _primaryKey); const allItems = await table.toArray(); const items = await filterItems(allItems, filter); return { data: items, total: items.length, success: true }; } catch (e) { return { data: [], total: 0, success: false, message: e.message }; } } async function get(keyValue, keyName) { var _a; try { const table = await db.getTable(tableName, _primaryKey); const searchKey = keyName !== null && keyName !== void 0 ? keyName : _primaryKey; const items = await table.toArray(); const item = (_a = items.find((row) => String(row[searchKey]) === keyValue)) !== null && _a !== void 0 ? _a : null; return { data: item, success: true }; } catch (e) { return { success: false, message: e.message }; } } async function create(item, uniqKey) { try { await delay(100); const table = await db.getTable(tableName, _primaryKey); const actualPk = db.getPrimaryKey(tableName); // Generate table primary key if missing const newItem = { ...item }; if (!(actualPk in newItem)) { newItem[actualPk] = getUuid(); } const keyToCheck = (uniqKey || actualPk); // Check uniqueness const existingRows = await table .filter((row) => String(row[keyToCheck]) === String(newItem[keyToCheck])) .toArray(); if (existingRows.length > 0) { return { success: false, message: `Duplicate key '${String(keyToCheck)}': ${newItem[keyToCheck]}`, }; } await table.add(newItem); return { data: newItem, success: true }; } catch (e) { return { success: false, message: e.message }; } } async function update(keyValue, updates, uniqKey) { try { const table = await db.getTable(tableName, _primaryKey); const keyToUse = uniqKey || _primaryKey; const allItems = await table.toArray(); let updatedItem = null; for (const currentItem of allItems) { if (String(currentItem[keyToUse]) !== keyValue) continue; debugger; // Merge updates const candidateItem = { ...currentItem, ...updates }; // Check uniqueness against all other items const duplicateExists = allItems.some((otherItem) => { return (String(otherItem[keyToUse]) === String(candidateItem[keyToUse]) && String(otherItem[_primaryKey]) !== String(currentItem[_primaryKey])); }); if (duplicateExists) { throw new Error(`Duplicate key '${String(keyToUse)}': ${candidateItem[keyToUse]}`); } await delay(100); await table.put(candidateItem); updatedItem = candidateItem; break; // stop after updating the first matching row } return { data: updatedItem, success: true }; } catch (e) { return { success: false, message: e.message }; } } async function _delete(keyValue, keyName) { try { const table = await db.getTable(tableName, _primaryKey); const searchKey = keyName !== null && keyName !== void 0 ? keyName : _primaryKey; const items = await table.toArray(); const toDelete = items.find((row) => String(row[searchKey]) === keyValue); if (toDelete) { // Use actual table primary key const actualPk = db.getPrimaryKey(tableName); await table.delete(toDelete[actualPk]); } return { success: true }; } catch (e) { return { success: false, message: e.message }; } } async function deleteAll(filter) { try { const table = await db.getTable(tableName, _primaryKey); await delay(100); if (!filter) { await table.clear(); } else { const items = await table.toArray(); const toKeep = items.filter((item) => !Object.entries(filter).every(([k, v]) => item[k] === v)); await table.clear(); await table.bulkPut(toKeep); } return { success: true }; } catch (e) { return { success: false, message: e.message }; } } return { list, get, create, delete: _delete, update, deleteAll, }; }