UNPKG

ngx-indexed-db

Version:
1,007 lines (995 loc) 41.7 kB
import * as i0 from '@angular/core'; import { InjectionToken, isDevMode, Inject, Injectable, assertInInjectionContext, inject, PLATFORM_ID, DOCUMENT, makeEnvironmentProviders, NgModule } from '@angular/core'; import { __decorate } from 'tslib'; import { Observable, from, combineLatest } from 'rxjs'; import { finalize, take } from 'rxjs/operators'; import { isPlatformBrowser } from '@angular/common'; var DBMode; (function (DBMode) { DBMode["readonly"] = "readonly"; DBMode["readwrite"] = "readwrite"; })(DBMode || (DBMode = {})); const CONFIG_TOKEN = new InjectionToken(null); const INDEXED_DB = new InjectionToken('Indexed DB'); /** * Token used to inject the indexed db implementation on the server */ const SERVER_INDEXED_DB = new InjectionToken('Server Indexed DB'); function validateStoreName(db, storeName) { return db.objectStoreNames.contains(storeName); } function validateBeforeTransaction(db, storeName, reject) { if (!db) { reject('You need to use the openDatabase function to create a database before you query it!'); return; // Stop further execution } if (!validateStoreName(db, storeName)) { reject(`objectStore does not exists: ${storeName}`); } } function createTransaction(db, options) { const trans = db.transaction(options.storeName, options.dbMode); trans.onerror = options.error; trans.onabort = options.abort; return trans; } function optionsGenerator(type, storeName, reject, // eslint-disable-next-line @typescript-eslint/no-unused-vars resolve) { return { storeName, dbMode: type, error: (e) => { reject(e); }, abort: (e) => { reject(e); }, }; } const openedDatabases = []; function openDatabase(indexedDB, dbName, version, upgradeCallback) { return new Promise((resolve, reject) => { if (!indexedDB) { reject('IndexedDB not available'); } const request = indexedDB.open(dbName, version); let db; request.onsuccess = () => { db = request.result; openedDatabases.push(db); resolve(db); }; request.onerror = () => { reject(`IndexedDB error: ${request.error}`); }; if (typeof upgradeCallback === 'function') { request.onupgradeneeded = (event) => { upgradeCallback(event, db); }; } }); } async function CreateObjectStore(indexedDB, dbName, version, storeSchemas, migrationFactory) { return new Promise((resolve, reject) => { if (!indexedDB) { return; } const request = indexedDB.open(dbName, version); request.onupgradeneeded = async (event) => { const database = event.target.result; const storeCreationPromises = storeSchemas.map(async (storeSchema) => { if (!database.objectStoreNames.contains(storeSchema.store)) { const objectStore = database.createObjectStore(storeSchema.store, storeSchema.storeConfig); for (const schema of storeSchema.storeSchema) { objectStore.createIndex(schema.name, schema.keypath, schema.options); } } }); await Promise.all(storeCreationPromises); const storeMigrations = migrationFactory && migrationFactory(); if (storeMigrations) { const migrationKeys = Object.keys(storeMigrations) .map((k) => parseInt(k, 10)) .filter((v) => v > event.oldVersion) .sort((a, b) => a - b); for (const v of migrationKeys) { storeMigrations[v](database, request.transaction); } } database.close(); resolve(); }; request.onsuccess = (e) => { e.target.result.close(); resolve(); }; request.onerror = (error) => { reject(error); }; }); } function DeleteObjectStore(dbName, version, storeName) { if (!dbName || !version || !storeName) { throw Error('Params: "dbName", "version", "storeName" are mandatory.'); } return new Observable((obs) => { try { const newVersion = version + 1; const request = indexedDB.open(dbName, newVersion); request.onupgradeneeded = (event) => { const database = event.target.result; database.deleteObjectStore(storeName); database.close(); console.log('onupgradeneeded'); obs.next(); obs.complete(); }; request.onerror = (e) => obs.error(e); } catch (error) { obs.error(error); } }); } function closeDatabase(db) { return new Promise((resolve, reject) => { if (!db) { reject(new Error('No database to close')); return; } try { db.close(); resolve(); } catch (error) { reject(`Error closing database: ${error}`); } }); } function CloseDbConnection() { return function (_target, _propertyKey, descriptor) { const originalMethod = descriptor.value; descriptor.value = function (...args) { const result = originalMethod.apply(this, args); if (result instanceof Observable) { return result.pipe(finalize(async () => { const promises = openedDatabases.map(async (db) => { await closeDatabase(db); }); await Promise.all(promises); openedDatabases.length = 0; })); } return result; }; return descriptor; }; } class NgxIndexedDBService { constructor(dbConfigs, indexedDB) { this.dbConfigs = dbConfigs; this.indexedDB = indexedDB; this.defaultDatabaseName = null; Object.values(this.dbConfigs).forEach((dbConfig, _, ref) => this.instanciateConfig(dbConfig, ref.length === 1)); } async instanciateConfig(dbConfig, isOnlyConfig) { if (!dbConfig.name) { throw new Error('NgxIndexedDB: Please, provide the dbName in the configuration'); } // if (!dbConfig.version) { // throw new Error('NgxIndexedDB: Please, provide the db version in the configuration'); // } if ((dbConfig.isDefault ?? false) && this.defaultDatabaseName) { // A default DB is already configured, throw an error throw new Error('NgxIndexedDB: Only one database can be set as default'); } if (((dbConfig.isDefault ?? false) && !this.defaultDatabaseName) || isOnlyConfig) { this.defaultDatabaseName = dbConfig.name; this.selectedDb = dbConfig.name; } await CreateObjectStore(this.indexedDB, dbConfig.name, dbConfig.version, dbConfig.objectStoresMeta, dbConfig.migrationFactory); openDatabase(this.indexedDB, dbConfig.name).then((db) => { if (db.version !== dbConfig.version) { if (isDevMode()) { console.warn(` Your DB Config doesn't match the most recent version of the DB with name ${dbConfig.name}, please update it DB current version: ${db.version}; Your configuration: ${dbConfig.version}; `); console.warn(`Using latest version ${db.version}`); } this.dbConfigs[dbConfig.name].version = db.version; } db.close(); }); } get dbConfig() { return this.dbConfigs[this.selectedDb]; } /** * The function return the current version of database * * @Return the current version of database as number */ getDatabaseVersion() { return new Observable((obs) => { openDatabase(this.indexedDB, this.dbConfig.name, this.dbConfig.version) .then((db) => { obs.next(db.version); obs.complete(); }) .catch((err) => obs.error(`error during get version of database => ${err} `)); }); } /** * Selects a database for the current context. * @param {string} [databaseName=undefined] Database name to select. */ selectDb(databaseName) { databaseName = databaseName ?? this.defaultDatabaseName; if (!databaseName) { // Name is still null, it means that there is no default database set // and the database name was not specified while calling a method throw new Error(`No database name specified and no default database set.`); } if (!Object.keys(this.dbConfigs).includes(databaseName)) { throw new Error(`NgxIndexedDB: Database ${databaseName} is not initialized.`); } this.selectedDb = databaseName; } /** * Allows to create a new object store ad-hoc * @param storeName The name of the store to be created * @param migrationFactory The migration factory if exists */ async createObjectStore(storeSchema, migrationFactory) { const storeSchemas = [storeSchema]; await CreateObjectStore(this.indexedDB, this.dbConfig.name, ++this.dbConfig.version, storeSchemas, migrationFactory); } /** * Create dynamic store if not already without incrementing version * For Dynamic store * @param storeName The name of the store to create */ async createDynamicObjectStore(storeSchema, migrationFactory) { const storeSchemas = [storeSchema]; await CreateObjectStore(this.indexedDB, this.dbConfig.name, this.dbConfig.version, storeSchemas, migrationFactory); } /** * Adds new entry in the store and returns its key * @param storeName The name of the store to add the item * @param value The entry to be added * @param key The optional key for the entry */ add(storeName, value, key) { return new Observable((obs) => { openDatabase(this.indexedDB, this.dbConfig.name, this.dbConfig.version) .then((db) => { const transaction = createTransaction(db, optionsGenerator(DBMode.readwrite, storeName, (e) => obs.error(e))); const objectStore = transaction.objectStore(storeName); const hasKey = Boolean(key); const request = hasKey ? objectStore.add(value, key) : objectStore.add(value); request.onsuccess = async (evt) => { const result = evt.target.result; const getRequest = objectStore.get(result); getRequest.onsuccess = (event) => { obs.next(event.target.result); obs.complete(); }; getRequest.onerror = (event) => { obs.error(event); }; }; request.onerror = (event) => { obs.error(event); }; }) .catch((error) => obs.error(error)); }); } /** * Adds new entries in the store and returns its key * @param storeName The name of the store to add the item * @param values The entries to be added containing optional key attribute */ bulkAdd(storeName, values) { const promises = new Promise((resolve, reject) => { openDatabase(this.indexedDB, this.dbConfig.name, this.dbConfig.version) .then((db) => { const transaction = createTransaction(db, optionsGenerator(DBMode.readwrite, storeName, resolve, reject)); const objectStore = transaction.objectStore(storeName); const results = values.map((value) => { return new Promise((resolve1) => { const key = value.key; delete value.key; const hasKey = Boolean(key); const request = hasKey ? objectStore.add(value, key) : objectStore.add(value); request.onsuccess = (evt) => { const result = evt.target.result; resolve1(result); }; }); }); resolve(Promise.all(results)); }) .catch((reason) => reject(reason)); }); return from(promises); } /** * Delete entries in the store and returns current entries in the store * @param storeName The name of the store to add the item * @param keys The keys to be deleted */ bulkDelete(storeName, keys) { const promises = keys.map((key) => { return new Promise((resolve, reject) => { openDatabase(this.indexedDB, this.dbConfig.name, this.dbConfig.version) .then((db) => { const transaction = createTransaction(db, optionsGenerator(DBMode.readwrite, storeName, reject, resolve)); const objectStore = transaction.objectStore(storeName); objectStore.delete(key); transaction.oncomplete = () => { this.getAll(storeName) .pipe(take(1)) .subscribe((newValues) => { resolve(newValues); }); }; }) .catch((reason) => reject(reason)); }); }); return from(Promise.all(promises)); } /** * Returns entry by key. * @param storeName The name of the store to query * @param key The entry key */ getByKey(storeName, key) { return new Observable((obs) => { openDatabase(this.indexedDB, this.dbConfig.name, this.dbConfig.version) .then((db) => { const transaction = createTransaction(db, optionsGenerator(DBMode.readonly, storeName, obs.error)); const objectStore = transaction.objectStore(storeName); const request = objectStore.get(key); request.onsuccess = (event) => { obs.next(event.target.result); obs.complete(); }; request.onerror = (event) => { obs.error(event); }; }) .catch((error) => obs.error(error)); }); } /** * Retrieve multiple entries in the store * @param storeName The name of the store to retrieve the items * @param keys The ids entries to be retrieve */ bulkGet(storeName, keys) { const observables = keys.map((key) => this.getByKey(storeName, key)); return new Observable((obs) => { combineLatest(observables).subscribe((values) => { obs.next(values); obs.complete(); }); }); } /** * Returns entry by id. * @param storeName The name of the store to query * @param id The entry id */ getByID(storeName, id) { return new Observable((obs) => { openDatabase(this.indexedDB, this.dbConfig.name, this.dbConfig.version) .then((db) => { validateBeforeTransaction(db, storeName, (e) => obs.error(e)); const transaction = createTransaction(db, optionsGenerator(DBMode.readonly, storeName, obs.error, obs.next)); const objectStore = transaction.objectStore(storeName); const request = objectStore.get(id); request.onsuccess = (event) => { obs.next(event.target.result); obs.complete(); }; }) .catch((error) => obs.error(error)); }); } /** * Returns entry by index. * @param storeName The name of the store to query * @param indexName The index name to filter * @param key The entry key. */ getByIndex(storeName, indexName, key) { return new Observable((obs) => { openDatabase(this.indexedDB, this.dbConfig.name, this.dbConfig.version) .then((db) => { validateBeforeTransaction(db, storeName, (e) => obs.error(e)); const transaction = createTransaction(db, optionsGenerator(DBMode.readonly, storeName, obs.error)); const objectStore = transaction.objectStore(storeName); const index = objectStore.index(indexName); const request = index.get(key); request.onsuccess = (event) => { obs.next(event.target.result); obs.complete(); }; }) .catch((reason) => obs.error(reason)); }); } /** * Return all elements from one store * @param storeName The name of the store to select the items */ getAll(storeName) { return new Observable((obs) => { openDatabase(this.indexedDB, this.dbConfig.name, this.dbConfig.version) .then((db) => { validateBeforeTransaction(db, storeName, (e) => obs.error(e)); const transaction = createTransaction(db, optionsGenerator(DBMode.readonly, storeName, obs.error, obs.next)); const objectStore = transaction.objectStore(storeName); const request = objectStore.getAll(); request.onerror = (evt) => { obs.error(evt); }; request.onsuccess = ({ target: { result: ResultAll } }) => { obs.next(ResultAll); obs.complete(); }; }) .catch((error) => obs.error(error)); }); } /** * Adds or updates a record in store with the given value and key. Return all items present in the store * @param storeName The name of the store to update * @param value The new value for the entry */ update(storeName, value) { return new Observable((obs) => { openDatabase(this.indexedDB, this.dbConfig.name, this.dbConfig.version) .then((db) => { validateBeforeTransaction(db, storeName, (e) => obs.error(e)); const transaction = createTransaction(db, optionsGenerator(DBMode.readwrite, storeName, (e) => obs.error(e))); const objectStore = transaction.objectStore(storeName); const request = objectStore.put(value); request.onsuccess = async (evt) => { const result = evt.target.result; const getRequest = objectStore.get(result); getRequest.onsuccess = (event) => { obs.next(event.target.result); obs.complete(); }; }; }) .catch((reason) => obs.error(reason)); }); } /** * Adds or updates a record in store with the given value and key. Return all items present in the store * @param storeName The name of the store to update * @param items The values to update in the DB * * @Return The return value is an Observable with the primary key of the object that was last in given array * * @error If the call to bulkPut fails the transaction will be aborted and previously inserted entities will be deleted */ bulkPut(storeName, items) { let transaction; return new Observable((obs) => { openDatabase(this.indexedDB, this.dbConfig.name, this.dbConfig.version) .then((db) => { validateBeforeTransaction(db, storeName, (e) => obs.error(e)); transaction = createTransaction(db, optionsGenerator(DBMode.readwrite, storeName, (e) => obs.error(e))); const objectStore = transaction.objectStore(storeName); items.forEach((item, index) => { const request = objectStore.put(item); if (index === items.length - 1) { request.onsuccess = (evt) => { transaction.commit(); obs.next(evt.target.result); obs.complete(); }; } request.onerror = (evt) => { transaction.abort(); obs.error(evt); }; }); }) .catch((reason) => { transaction?.abort(); obs.error(reason); }); }); } /** * Returns all items from the store after delete. * @param storeName The name of the store to have the entry deleted * @param query The key or key range criteria to apply */ delete(storeName, query) { return new Observable((obs) => { openDatabase(this.indexedDB, this.dbConfig.name, this.dbConfig.version) .then((db) => { validateBeforeTransaction(db, storeName, (e) => obs.error(e)); const transaction = createTransaction(db, optionsGenerator(DBMode.readwrite, storeName, (e) => obs.error(e))); const objectStore = transaction.objectStore(storeName); objectStore.delete(query); transaction.onerror = (e) => obs.error(e); transaction.oncomplete = () => { this.getAll(storeName) .pipe(take(1)) .subscribe({ next: (newValues) => { obs.next(newValues); }, error: (e) => obs.error(e), complete: () => obs.complete(), }); }; }) .catch((reason) => obs.error(reason)); }); } /** * Returns after a successful delete. * @param storeName The name of the store to have the entry deleted * @param query The key or key range criteria to apply */ deleteByKey(storeName, query) { return new Observable((obs) => { openDatabase(this.indexedDB, this.dbConfig.name, this.dbConfig.version) .then((db) => { validateBeforeTransaction(db, storeName, (e) => obs.error(e)); const transaction = createTransaction(db, optionsGenerator(DBMode.readwrite, storeName, (e) => obs.error(e))); const objectStore = transaction.objectStore(storeName); objectStore.delete(query); transaction.onerror = (e) => obs.error(e); transaction.oncomplete = () => { obs.next(); obs.complete(); }; }) .catch((reason) => obs.error(reason)); }); } /** * Delete all items by an index. * @param storeName The name of the store to query * @param indexName The index name to filter * @param query The key or key range criteria to apply * @param direction A string telling the cursor which direction to travel. */ deleteAllByIndex(storeName, indexName, query, direction) { return new Observable((obs) => { openDatabase(this.indexedDB, this.dbConfig.name, this.dbConfig.version) .then((db) => { validateBeforeTransaction(db, storeName, (e) => obs.error(e)); const transaction = createTransaction(db, optionsGenerator(DBMode.readwrite, storeName, obs.error)); const objectStore = transaction.objectStore(storeName); const index = objectStore.index(indexName); const request = index.openCursor(query, direction); request.onerror = (e) => obs.error(e); request.onsuccess = (event) => { const cursor = event.target.result; if (cursor) { cursor.delete(); cursor.continue(); } else { obs.next(); obs.complete(); } }; }) .catch((reason) => obs.error(reason)); }); } /** * Clear the data in the objectStore. * @param storeName The name of the store to have the entries deleted */ clear(storeName) { return new Observable((obs) => { openDatabase(this.indexedDB, this.dbConfig.name, this.dbConfig.version) .then((db) => { validateBeforeTransaction(db, storeName, (e) => obs.error(e)); const transaction = createTransaction(db, optionsGenerator(DBMode.readwrite, storeName, (e) => obs.error(e))); const objectStore = transaction.objectStore(storeName); objectStore.clear(); transaction.onerror = (e) => obs.error(e); transaction.oncomplete = () => { obs.next(); obs.complete(); }; }) .catch((reason) => obs.error(reason)); }); } /** * Delete database. */ deleteDatabase() { return new Observable((obs) => { openDatabase(this.indexedDB, this.dbConfig.name, this.dbConfig.version) .then(async (db) => { db.close(); const deleteDBRequest = this.indexedDB.deleteDatabase(this.dbConfig.name); deleteDBRequest.onsuccess = () => { obs.next(); obs.complete(); }; deleteDBRequest.onerror = (error) => obs.error(error); deleteDBRequest.onblocked = () => { console.warn('Delete blocked: Ensure all tabs, instances, or connections are closed. Database name:', this.dbConfig.name); obs.error(new Error("Unable to delete database because it's blocked")); }; }) .catch((error) => obs.error(error)); }); } /** * Returns the open cursor * If no matching data are present, the observable is completed immediately. * @param options The options to open the cursor * @param options.storeName The name of the store to have the entries deleted * @param options.query The key or key range criteria to apply * @param options.direction A string telling the cursor which direction to travel * @param options.mode The transaction mode. */ openCursor(options) { const { storeName, query, direction, mode = DBMode.readonly } = options; return new Observable((obs) => { openDatabase(this.indexedDB, this.dbConfig.name, this.dbConfig.version) .then((db) => { validateBeforeTransaction(db, storeName, (e) => obs.error(e)); const transaction = createTransaction(db, optionsGenerator(mode, storeName, obs.error)); const objectStore = transaction.objectStore(storeName); const request = objectStore.openCursor(query, direction); transaction.oncomplete = () => obs.complete(); request.onerror = (e) => obs.error(e); request.onsuccess = (event) => { const cursor = event.target.result; if (cursor) { obs.next(cursor); } }; }) .catch((reason) => obs.error(reason)); }); } /** * Open a cursor by index filter * If no matching data are present, the observable is completed immediately. * @param options The options to open the cursor * @param options.storeName The name of the store to query * @param options.indexName The index name to filter * @param options.query The key or key range criteria to apply * @param options.direction A string telling the cursor which direction to travel * @param options.mode The transaction mode. */ openCursorByIndex(options) { const { storeName, indexName, query, direction, mode = DBMode.readonly } = options; return new Observable((obs) => { openDatabase(this.indexedDB, this.dbConfig.name, this.dbConfig.version) .then((db) => { validateBeforeTransaction(db, storeName, (e) => obs.error(e)); const transaction = createTransaction(db, optionsGenerator(mode, storeName, obs.error)); const objectStore = transaction.objectStore(storeName); const index = objectStore.index(indexName); const request = index.openCursor(query, direction); transaction.oncomplete = () => obs.complete(); request.onerror = (e) => obs.error(e); request.onsuccess = (event) => { const cursor = event.target.result; if (cursor) { obs.next(cursor); } }; }) .catch((reason) => obs.error(reason)); }); } /** * Returns all items by an index. * @param storeName The name of the store to query * @param indexName The index name to filter * @param query The key or key range criteria to apply * @param direction A string telling the cursor which direction to travel. */ getAllByIndex(storeName, indexName, query, direction) { return new Observable((obs) => { openDatabase(this.indexedDB, this.dbConfig.name, this.dbConfig.version) .then((db) => { validateBeforeTransaction(db, storeName, (e) => obs.error(e)); const transaction = createTransaction(db, optionsGenerator(DBMode.readonly, storeName, obs.error)); const objectStore = transaction.objectStore(storeName); const index = objectStore.index(indexName); const request = index.openCursor(query, direction); const data = []; request.onerror = (e) => obs.error(e); request.onsuccess = (event) => { const cursor = event.target.result; if (cursor) { data.push(cursor.value); cursor.continue(); } else { obs.next(data); obs.complete(); } }; }) .catch((reason) => obs.error(reason)); }); } /** * Returns all primary keys by an index. * @param storeName The name of the store to query * @param query The key or key range criteria to apply * @param direction A string telling the cursor which direction to travel. */ getAllKeysByIndex(storeName, indexName, query, direction) { return new Observable((obs) => { openDatabase(this.indexedDB, this.dbConfig.name, this.dbConfig.version) .then((db) => { validateBeforeTransaction(db, storeName, (e) => obs.error(e)); const transaction = createTransaction(db, optionsGenerator(DBMode.readonly, storeName, obs.error)); const objectStore = transaction.objectStore(storeName); const index = objectStore.index(indexName); const data = []; const request = index.openKeyCursor(query, direction); request.onerror = (e) => obs.error(e); request.onsuccess = (event) => { const cursor = event.target.result; if (cursor) { const { primaryKey, key } = cursor; data.push({ primaryKey, key, }); cursor.continue(); } else { obs.next(data); obs.complete(); } }; }) .catch((reason) => obs.error(reason)); }); } /** * Returns the number of rows in a store. * @param storeName The name of the store to query * @param query The key or key range criteria to apply. */ count(storeName, query) { return new Observable((obs) => { openDatabase(this.indexedDB, this.dbConfig.name, this.dbConfig.version) .then((db) => { validateBeforeTransaction(db, storeName, (e) => obs.error(e)); const transaction = createTransaction(db, optionsGenerator(DBMode.readonly, storeName, obs.error)); const objectStore = transaction.objectStore(storeName); const request = objectStore.count(query); request.onerror = (e) => obs.error(e); request.onsuccess = (e) => { obs.next(e.target.result); obs.complete(); }; }) .catch((reason) => obs.error(reason)); }); } /** * Returns the number of records within a key range. * @param storeName The name of the store to query * @param indexName The index name to filter * @param query The key or key range criteria to apply. */ countByIndex(storeName, indexName, query) { return new Observable((obs) => { openDatabase(this.indexedDB, this.dbConfig.name, this.dbConfig.version) .then((db) => { validateBeforeTransaction(db, storeName, (e) => obs.error(e)); const transaction = createTransaction(db, optionsGenerator(DBMode.readonly, storeName, obs.error)); const objectStore = transaction.objectStore(storeName); const index = objectStore.index(indexName); const request = index.count(query); request.onerror = (e) => obs.error(e); request.onsuccess = (e) => { obs.next(e.target.result); obs.complete(); }; }) .catch((reason) => obs.error(reason)); }); } /** * Delete the store by name. * @param storeName The name of the store to query */ deleteObjectStore(storeName) { return DeleteObjectStore(this.dbConfig.name, ++this.dbConfig.version, storeName); } /** * Get all object store names. */ getAllObjectStoreNames() { return new Observable((obs) => { openDatabase(this.indexedDB, this.dbConfig.name, this.dbConfig.version) .then((db) => { obs.next(Array.from(db.objectStoreNames)); obs.complete(); }) .catch((reason) => obs.error(reason)); }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: NgxIndexedDBService, deps: [{ token: CONFIG_TOKEN }, { token: INDEXED_DB }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: NgxIndexedDBService }); } } __decorate([ CloseDbConnection() ], NgxIndexedDBService.prototype, "getDatabaseVersion", null); __decorate([ CloseDbConnection() ], NgxIndexedDBService.prototype, "add", null); __decorate([ CloseDbConnection() ], NgxIndexedDBService.prototype, "bulkAdd", null); __decorate([ CloseDbConnection() ], NgxIndexedDBService.prototype, "bulkDelete", null); __decorate([ CloseDbConnection() ], NgxIndexedDBService.prototype, "getByKey", null); __decorate([ CloseDbConnection() ], NgxIndexedDBService.prototype, "bulkGet", null); __decorate([ CloseDbConnection() ], NgxIndexedDBService.prototype, "getByID", null); __decorate([ CloseDbConnection() ], NgxIndexedDBService.prototype, "getByIndex", null); __decorate([ CloseDbConnection() ], NgxIndexedDBService.prototype, "getAll", null); __decorate([ CloseDbConnection() ], NgxIndexedDBService.prototype, "update", null); __decorate([ CloseDbConnection() ], NgxIndexedDBService.prototype, "bulkPut", null); __decorate([ CloseDbConnection() ], NgxIndexedDBService.prototype, "delete", null); __decorate([ CloseDbConnection() ], NgxIndexedDBService.prototype, "deleteByKey", null); __decorate([ CloseDbConnection() ], NgxIndexedDBService.prototype, "deleteAllByIndex", null); __decorate([ CloseDbConnection() ], NgxIndexedDBService.prototype, "clear", null); __decorate([ CloseDbConnection() ], NgxIndexedDBService.prototype, "deleteDatabase", null); __decorate([ CloseDbConnection() ], NgxIndexedDBService.prototype, "openCursor", null); __decorate([ CloseDbConnection() ], NgxIndexedDBService.prototype, "openCursorByIndex", null); __decorate([ CloseDbConnection() ], NgxIndexedDBService.prototype, "getAllByIndex", null); __decorate([ CloseDbConnection() ], NgxIndexedDBService.prototype, "getAllKeysByIndex", null); __decorate([ CloseDbConnection() ], NgxIndexedDBService.prototype, "count", null); __decorate([ CloseDbConnection() ], NgxIndexedDBService.prototype, "countByIndex", null); __decorate([ CloseDbConnection() ], NgxIndexedDBService.prototype, "getAllObjectStoreNames", null); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: NgxIndexedDBService, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: undefined, decorators: [{ type: Inject, args: [CONFIG_TOKEN] }] }, { type: IDBFactory, decorators: [{ type: Inject, args: [INDEXED_DB] }] }], propDecorators: { getDatabaseVersion: [], add: [], bulkAdd: [], bulkDelete: [], getByKey: [], bulkGet: [], getByID: [], getByIndex: [], getAll: [], update: [], bulkPut: [], delete: [], deleteByKey: [], deleteAllByIndex: [], clear: [], deleteDatabase: [], openCursor: [], openCursorByIndex: [], getAllByIndex: [], getAllKeysByIndex: [], count: [], countByIndex: [], getAllObjectStoreNames: [] } }); /** * * A class that implements the IDBFactory interface, but only for the server. * All methods return a mocked value. * */ class ServerIndexedDB { cmp() { return 0; } databases() { return Promise.resolve([]); } deleteDatabase() { return { onupgradeneeded: null, onblocked: null, onerror: null, onsuccess: null, error: null, }; } open() { return { onupgradeneeded: null, onblocked: null, onerror: null, onsuccess: null, error: null, }; } } /** * Factory function for creating an instance of IDBFactory. * * It determines the platform using the {@link PLATFORM_ID} to decide whether to use the * browser's IndexedDB or a server-side implementation. * * @returns {IDBFactory} IDBFactory. */ function indexedDbFactory() { assertInInjectionContext(indexedDbFactory); const platformId = inject(PLATFORM_ID); const serverIndexedDB = inject(SERVER_INDEXED_DB, { optional: true }) ?? new ServerIndexedDB(); return isPlatformBrowser(platformId) ? inject(DOCUMENT).defaultView.indexedDB : serverIndexedDB; } const provideIndexedDb = (...dbConfigs) => { return makeEnvironmentProviders([..._provideIndexedDb(...dbConfigs)]); }; const _provideIndexedDb = (...dbConfigs) => { const configs = dbConfigs.reduce((acc, curr) => { acc[curr.name] = curr; return acc; }, {}); return [ NgxIndexedDBService, { provide: CONFIG_TOKEN, useValue: configs }, { provide: INDEXED_DB, useFactory: indexedDbFactory }, ]; }; class NgxIndexedDBModule { static forRoot(...dbConfigs) { return { ngModule: NgxIndexedDBModule, providers: [..._provideIndexedDb(...dbConfigs)], }; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: NgxIndexedDBModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.2", ngImport: i0, type: NgxIndexedDBModule }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: NgxIndexedDBModule }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: NgxIndexedDBModule, decorators: [{ type: NgModule }] }); /** * Generated bundle index. Do not edit. */ export { CONFIG_TOKEN, DBMode, INDEXED_DB, NgxIndexedDBModule, NgxIndexedDBService, SERVER_INDEXED_DB, provideIndexedDb }; //# sourceMappingURL=ngx-indexed-db.mjs.map