angular-11-indexeddb
Version:
A powerful and flexible Angular 11 library for managing client-side storage using IndexedDB with support for cache expiration and CRUD operations.
297 lines (290 loc) • 13.6 kB
JavaScript
import { __awaiter } from 'tslib';
import * as i0 from '@angular/core';
import { InjectionToken, Injectable, Inject } from '@angular/core';
// Define InjectionTokens for dbName and storeName
const DB_NAME = new InjectionToken('DB_NAME');
const STORE_NAME = new InjectionToken('STORE_NAME');
const CACHED_TIME = new InjectionToken('CACHED_TIME'); // Add new token for cached time
class DataToStore {
constructor(id, value) {
this.cachedTime = null;
this.id = id;
this.value = value;
this.savedTime = new Date().toISOString(); // Generate the current timestamp
}
}
class IndexedDbHandler {
constructor(dbName, storeName, cachedTime) {
this.dbName = dbName;
this.storeName = storeName;
this.cachedTime = cachedTime;
this.dbInitialized = this.initDB();
}
/**
* Ensures that the database is fully set up before performing any operations.
* @returns A promise that resolves when the IndexedDB is initialized.
*/
whenInitialized() {
return __awaiter(this, void 0, void 0, function* () {
return this.dbInitialized;
});
}
/**
* Initializes the IndexedDB and creates the object store if it doesn't exist.
* @returns A promise that resolves to the IndexedDB instance.
*/
initDB() {
return new Promise((resolve, reject) => {
const request = indexedDB.open(this.dbName);
request.onupgradeneeded = (event) => {
const db = event.target.result;
if (!db.objectStoreNames.contains(this.storeName)) {
db.createObjectStore(this.storeName, { keyPath: 'id' });
console.info(`Object store '${this.storeName}' created.`);
}
};
request.onsuccess = (event) => {
const db = event.target.result;
resolve(db);
};
request.onerror = (event) => {
console.error('Error opening IndexedDB:', event);
reject(event.target.error);
};
});
}
/**
* Saves data to the IndexedDB.
* @param key The key used to store the data.
* @param value The data to be saved.
* @param cacheTime Optional parameter to specify the cache time for the data.
* @returns A promise that resolves when the data is saved.
*/
saveData(key, value, cacheTime = null) {
return __awaiter(this, void 0, void 0, function* () {
yield this.whenInitialized(); // Ensure DB is initialized
const db = yield this.whenInitialized();
const transaction = db.transaction(this.storeName, 'readwrite');
const store = transaction.objectStore(this.storeName);
// Create a new instance of the DataToStore class
const dataToStore = new DataToStore(key, value);
dataToStore.cachedTime = cacheTime; // Set the cacheTime (null if not provided)
return new Promise((resolve, reject) => {
const request = store.put(dataToStore); // Save the object
request.onsuccess = () => {
resolve();
};
request.onerror = (event) => {
reject(`Error saving data: ${event}`);
};
});
});
}
/**
* Retrieves data from the IndexedDB by key.
* @param key The key of the data to retrieve.
* @returns A promise that resolves to the data or null if not found or expired.
*/
getData(key) {
return __awaiter(this, void 0, void 0, function* () {
yield this.whenInitialized(); // Ensure DB is initialized
const db = yield this.whenInitialized();
const transaction = db.transaction(this.storeName, 'readonly');
const store = transaction.objectStore(this.storeName);
return new Promise((resolve, reject) => {
const request = store.get(key); // Retrieve data by key
request.onsuccess = () => __awaiter(this, void 0, void 0, function* () {
if (request.result === undefined) {
resolve(null); // Return null if no data found
}
else {
// Check expiration based on cachedTime or CACHED_TIME
const cachedTime = request.result.cachedTime;
let isExpired = false;
if (cachedTime === null) {
// If cachedTime is null, use the default CACHED_TIME for expiration check
isExpired = yield this.checkIfExpired(request.result.savedTime, this.cachedTime);
}
else {
// If cachedTime exists, check against it
isExpired = yield this.checkIfExpired(request.result.savedTime, cachedTime);
}
if (isExpired) {
resolve(null); // Return null if data is expired
}
else {
resolve(request.result.value); // Return the value if not expired
}
}
});
request.onerror = (event) => {
reject(`Error retrieving data: ${event}`);
};
});
});
}
/**
* Removes data from the IndexedDB by key.
* @param key The key of the data to remove.
* @returns A promise that resolves when the data is removed.
*/
removeData(key) {
return __awaiter(this, void 0, void 0, function* () {
yield this.whenInitialized(); // Ensure DB is initialized
const db = yield this.whenInitialized();
const transaction = db.transaction(this.storeName, 'readwrite');
const store = transaction.objectStore(this.storeName);
return new Promise((resolve, reject) => {
const request = store.delete(key); // Delete data by key
request.onsuccess = () => {
resolve(); // Resolve when the data is removed
};
request.onerror = (event) => {
reject(`Error removing data: ${event}`);
};
});
});
}
/**
* Updates data in the IndexedDB by key.
* @param key The key of the data to update.
* @param value The new data to update.
* @returns A promise that resolves when the data is updated.
*/
updateData(key, value) {
return __awaiter(this, void 0, void 0, function* () {
yield this.whenInitialized(); // Ensure DB is initialized
const db = yield this.whenInitialized();
const transaction = db.transaction(this.storeName, 'readwrite');
const store = transaction.objectStore(this.storeName);
// Create a new instance of the DataToStore class
const dataToStore = new DataToStore(key, value);
return new Promise((resolve, reject) => {
const request = store.put(dataToStore); // Save the object
request.onsuccess = () => {
resolve();
};
request.onerror = (event) => {
reject(`Error saving data: ${event}`);
};
});
});
}
/**
* Retrieves all data from the IndexedDB store.
* Filters out expired data based on the cache time or default expiration time.
* @returns A promise that resolves to an array of all valid data items.
*/
getAll() {
return __awaiter(this, void 0, void 0, function* () {
yield this.whenInitialized(); // Ensure DB is initialized
const db = yield this.whenInitialized();
const transaction = db.transaction(this.storeName, 'readonly');
const store = transaction.objectStore(this.storeName);
return new Promise((resolve, reject) => {
const getRequest = store.getAll(); // Get all records from the store
// Handle success
getRequest.onsuccess = () => __awaiter(this, void 0, void 0, function* () {
const result = getRequest.result;
if (result === undefined || result.length === 0) {
resolve([]); // Return an empty array if no data found
}
else {
// Filter out expired items using cachedTime or CACHED_TIME
const filteredResults = yield Promise.all(result.map((item) => __awaiter(this, void 0, void 0, function* () {
let isExpired = false;
const cachedTime = item.cachedTime;
if (cachedTime === null) {
// If cachedTime is null, compare against CACHED_TIME
isExpired = yield this.checkIfExpired(item.savedTime, this.cachedTime);
}
else {
// Compare against cachedTime
isExpired = yield this.checkIfExpired(item.savedTime, cachedTime);
}
return isExpired ? null : item.value; // Exclude expired items
})));
// Filter out null values (expired data)
resolve(filteredResults.filter(item => item !== null));
}
});
// Handle error
getRequest.onerror = (event) => {
reject(`Error retrieving all data from IndexedDB: ${event}`);
};
});
});
}
/**
* Clears all data in the IndexedDB store.
* @returns A promise that resolves when the store is cleared.
*/
clearStore() {
return __awaiter(this, void 0, void 0, function* () {
yield this.whenInitialized(); // Ensure DB is initialized
const db = yield this.whenInitialized();
const transaction = db.transaction(this.storeName, 'readwrite'); // Open a transaction in 'readwrite' mode
const store = transaction.objectStore(this.storeName);
return new Promise((resolve, reject) => {
const request = store.clear(); // Clear all records in the store
request.onsuccess = () => {
resolve(); // Resolve if the store is cleared successfully
};
request.onerror = (event) => {
reject(`Error clearing the store: ${event}`); // Reject if there's an error
};
});
});
}
/**
* Getter for the cached time value.
* @returns The current cached time value.
*/
getCachedTime() {
return this.cachedTime;
}
/**
* Setter for the cached time value.
* @param newCachedTime The new cached time value to set.
*/
setCachedTime(newCachedTime) {
this.cachedTime = newCachedTime; // Update the cachedTime value
}
/**
* Checks if the data has expired based on the saved time and comparison time.
* @param savedTime The saved time of the data.
* @param comparisonTimeInMs The comparison time in milliseconds.
* @returns A promise that resolves to a boolean indicating if the data is expired.
*/
checkIfExpired(savedTime, comparisonTimeInMs) {
return __awaiter(this, void 0, void 0, function* () {
if (comparisonTimeInMs === 0) {
return false; // If comparisonTime is 0, data never expires
}
const currentTime = new Date().getTime(); // Get current time in milliseconds
const savedTimeStamp = new Date(savedTime).getTime(); // Convert savedTime to milliseconds
const difference = currentTime - savedTimeStamp; // Calculate time difference
// Check if the time difference exceeds the comparisonTime (in milliseconds)
return difference > comparisonTimeInMs;
});
}
}
IndexedDbHandler.ɵprov = i0.ɵɵdefineInjectable({ factory: function IndexedDbHandler_Factory() { return new IndexedDbHandler(i0.ɵɵinject(DB_NAME), i0.ɵɵinject(STORE_NAME), i0.ɵɵinject(CACHED_TIME)); }, token: IndexedDbHandler, providedIn: "root" });
IndexedDbHandler.decorators = [
{ type: Injectable, args: [{
providedIn: 'root',
},] }
];
IndexedDbHandler.ctorParameters = () => [
{ type: String, decorators: [{ type: Inject, args: [DB_NAME,] }] },
{ type: String, decorators: [{ type: Inject, args: [STORE_NAME,] }] },
{ type: Number, decorators: [{ type: Inject, args: [CACHED_TIME,] }] }
];
/*
* Public API Surface of angular-11-indexeddb
*/
/**
* Generated bundle index. Do not edit.
*/
export { CACHED_TIME, DB_NAME, DataToStore, IndexedDbHandler, STORE_NAME };
//# sourceMappingURL=angular-11-indexeddb.js.map