react-indexeddb-toolkit
Version:
A complete TypeScript toolkit for IndexedDB in React applications
102 lines (101 loc) • 3.1 kB
JavaScript
import { useState, useEffect, useCallback } from "react";
import { IndexedDBManager } from "../IndexedDBManager";
export function useIndexedDB(config) {
const [data, setData] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
const storeName = config.store ??
(config.stores.length === 1
? config.stores[0].name
: (() => {
throw new Error("Must specify a store when you have multiple");
})());
const [dbManager] = useState(() => new IndexedDBManager({ ...config, store: storeName }));
const keyPath = config.stores.find((s) => s.name === storeName)?.keyPath || "id";
const loadData = useCallback(async () => {
try {
setIsLoading(true);
setError(null);
const items = await dbManager.getAll();
setData(items);
}
catch (err) {
setError(err.message || "Failed to load data");
}
finally {
setIsLoading(false);
}
}, [dbManager]);
const save = useCallback(async (item) => {
try {
setError(null);
await dbManager.save(item);
await loadData();
}
catch (err) {
setError(err.message || "Failed to save item");
throw err;
}
}, [dbManager, loadData]);
const remove = useCallback(async (id) => {
try {
setError(null);
await dbManager.delete(id);
setData((prev) => prev.filter((item) => item[keyPath || "id"] !== id));
}
catch (err) {
setError(err.message || "Failed to delete item");
throw err;
}
}, [dbManager, keyPath]);
const update = useCallback(async (id, updates) => {
try {
setError(null);
const existing = await dbManager.getById(id);
if (existing) {
const updated = { ...existing, ...updates };
await dbManager.save(updated);
await loadData();
}
}
catch (err) {
setError(err.message || "Failed to update item");
throw err;
}
}, [dbManager, loadData]);
const findById = useCallback(async (id) => {
try {
setError(null);
return await dbManager.getById(id);
}
catch (err) {
setError(err.message || "Failed to find item");
return null;
}
}, [dbManager]);
const clear = useCallback(async () => {
try {
setError(null);
await dbManager.clear();
setData([]);
}
catch (err) {
setError(err.message || "Failed to clear data");
throw err;
}
}, [dbManager]);
useEffect(() => {
loadData();
}, [loadData]);
return {
data,
isLoading,
error,
save,
remove,
update,
findById,
clear,
refresh: loadData,
};
}