UNPKG

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
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