UNPKG

ng-indexed-db

Version:

An IndexedDB Angular module wrapped in RXJS

804 lines (796 loc) 24.1 kB
import { Injectable, InjectionToken, Inject, NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { map, switchMap, skipWhile } from 'rxjs/operators'; import { __assign } from 'tslib'; import { Observable, timer, forkJoin } from 'rxjs'; import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @enum {string} */ var TransactionModes = { READONLY: 'readonly', READWRITE: 'readwrite', }; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * IndexedDB client */ var /** * IndexedDB client */ IndexedDatabase = /** @class */ (function () { function IndexedDatabase(database, upgraded, stores) { if (stores === void 0) { stores = []; } this.database = database; this.upgraded = upgraded; this.createTables(stores); } /** * If table has been upgrades, generates the recived stores * @param tables Tables metadata */ /** * If table has been upgrades, generates the recived stores * @param {?} tables Tables metadata * @return {?} */ IndexedDatabase.prototype.createTables = /** * If table has been upgrades, generates the recived stores * @param {?} tables Tables metadata * @return {?} */ function (tables) { var _this = this; if (this.upgraded) { tables.forEach((/** * @param {?} item * @return {?} */ function (item) { return _this.createTable(item); })); } }; /** * Generates one single sotre * @param storeName Store name */ /** * Generates one single sotre * @param {?} store * @return {?} */ IndexedDatabase.prototype.createTable = /** * Generates one single sotre * @param {?} store * @return {?} */ function (store) { /** @type {?} */ var keyPath = 'id'; this.database.createObjectStore(store.name, { keyPath: keyPath }); }; /** * Request a list with all store elements * @param storeName Store name */ /** * Request a list with all store elements * @template M * @param {?} storeName Store name * @return {?} */ IndexedDatabase.prototype.list = /** * Request a list with all store elements * @template M * @param {?} storeName Store name * @return {?} */ function (storeName) { var _this = this; return new Observable((/** * @param {?} observer * @return {?} */ function (observer) { /** @type {?} */ var store = _this.store(storeName, TransactionModes.READONLY); /** @type {?} */ var request = store.getAll(); request.onsuccess = (/** * @param {?} event * @return {?} */ function (event) { return observer.next(request.result); }); request.onerror = (/** * @param {?} event * @return {?} */ function (event) { return observer.error(request.error); }); })); }; /** * Request a single object found by the given key * @param storeName Store name * @param key Predicate key */ /** * Request a single object found by the given key * @template M * @param {?} storeName Store name * @param {?} key Predicate key * @return {?} */ IndexedDatabase.prototype.get = /** * Request a single object found by the given key * @template M * @param {?} storeName Store name * @param {?} key Predicate key * @return {?} */ function (storeName, key) { var _this = this; return new Observable((/** * @param {?} observer * @return {?} */ function (observer) { /** @type {?} */ var store = _this.store(storeName, TransactionModes.READONLY); /** @type {?} */ var request = store.get(key); request.onsuccess = (/** * @param {?} event * @return {?} */ function (event) { return observer.next(request.result); }); request.onerror = (/** * @param {?} event * @return {?} */ function (event) { return observer.error(request.error); }); })); }; /** * Request to store an element * @param storeName Store name * @param data data to store */ /** * Request to store an element * @template M * @param {?} storeName Store name * @param {?} data data to store * @return {?} */ IndexedDatabase.prototype.create = /** * Request to store an element * @template M * @param {?} storeName Store name * @param {?} data data to store * @return {?} */ function (storeName, data) { var _this = this; return new Observable((/** * @param {?} observer * @return {?} */ function (observer) { /** @type {?} */ var store = _this.store(storeName, TransactionModes.READWRITE); /** @type {?} */ var request = store.put(data); request.onsuccess = (/** * @param {?} event * @return {?} */ function (event) { return observer.next(data); }); request.onerror = (/** * @param {?} event * @return {?} */ function (event) { return observer.error(request.error); }); })); }; /** * Request to update an element * @param storeName Store name * @param data data to store */ /** * Request to update an element * @template M * @param {?} storeName Store name * @param {?} data data to store * @return {?} */ IndexedDatabase.prototype.update = /** * Request to update an element * @template M * @param {?} storeName Store name * @param {?} data data to store * @return {?} */ function (storeName, data) { var _this = this; return new Observable((/** * @param {?} observer * @return {?} */ function (observer) { /** @type {?} */ var store = _this.store(storeName, TransactionModes.READWRITE); /** @type {?} */ var request = store.put(data); request.onsuccess = (/** * @param {?} event * @return {?} */ function (event) { return observer.next(data); }); request.onerror = (/** * @param {?} event * @return {?} */ function (event) { return observer.error(request.error); }); })); }; /** * Request to delete an element with the given key * @param storeName Store name * @param key Element key to delete */ /** * Request to delete an element with the given key * @param {?} storeName Store name * @param {?} key Element key to delete * @return {?} */ IndexedDatabase.prototype.delete = /** * Request to delete an element with the given key * @param {?} storeName Store name * @param {?} key Element key to delete * @return {?} */ function (storeName, key) { var _this = this; return new Observable((/** * @param {?} observer * @return {?} */ function (observer) { /** @type {?} */ var store = _this.store(storeName, TransactionModes.READWRITE); /** @type {?} */ var request = store.delete(key); request.onsuccess = (/** * @param {?} event * @return {?} */ function (event) { return observer.next(true); }); request.onerror = (/** * @param {?} event * @return {?} */ function (event) { return observer.error(request.error); }); })); }; /** * Find the a store table by the given name * @param storeName Store name to find * @param mode Transaction mode */ /** * Find the a store table by the given name * @private * @param {?} storeName Store name to find * @param {?} mode Transaction mode * @return {?} */ IndexedDatabase.prototype.store = /** * Find the a store table by the given name * @private * @param {?} storeName Store name to find * @param {?} mode Transaction mode * @return {?} */ function (storeName, mode) { /** @type {?} */ var transaction = this.database.transaction(storeName, mode); /** @type {?} */ var store = transaction.objectStore(storeName); return store; }; return IndexedDatabase; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ var NgDatabaseFactory = /** @class */ (function () { function NgDatabaseFactory() { /** * Emits an event when all databases recive has been generated */ this.connectionsReady = new BehaviorSubject(false); /** * Indexed database connection factory */ this.factory = window.indexedDB; } /** * Sends the database metadata to create. * Once it has been completed, emits the * connectionsReady event * @param databases Databases metadata */ /** * Sends the database metadata to create. * Once it has been completed, emits the * connectionsReady event * @param {?} databases Databases metadata * @return {?} */ NgDatabaseFactory.prototype.createConnnections = /** * Sends the database metadata to create. * Once it has been completed, emits the * connectionsReady event * @param {?} databases Databases metadata * @return {?} */ function (databases) { var _this = this; this.createDataBases(databases) .pipe(map((/** * @param {?} response * @return {?} */ function (response) { return _this.connections = response; })), switchMap((/** * @param {?} response * @return {?} */ function (response) { return timer(100); }))) .subscribe((/** * @return {?} */ function () { return _this.connectionsReady.next(true); })); }; /** * Find a database connection by name. If there isn't * a database name takes the default database name * @param dbName Name of the database alias */ /** * Find a database connection by name. If there isn't * a database name takes the default database name * @param {?=} dbName Name of the database alias * @return {?} */ NgDatabaseFactory.prototype.getDatabase = /** * Find a database connection by name. If there isn't * a database name takes the default database name * @param {?=} dbName Name of the database alias * @return {?} */ function (dbName) { return this.connections[dbName ? dbName : this.defaultConnectionName]; }; /** * Open a database connection * @param dbName name of the database * @param version version of the database */ /** * Open a database connection * @param {?} dbName name of the database * @param {?=} version version of the database * @return {?} */ NgDatabaseFactory.prototype.open = /** * Open a database connection * @param {?} dbName name of the database * @param {?=} version version of the database * @return {?} */ function (dbName, version) { var _this = this; return new Observable((/** * @param {?} observer * @return {?} */ function (observer) { /** @type {?} */ var upgraded = false; /** @type {?} */ var DBOpenRequest = _this.factory.open(dbName, version); DBOpenRequest.onupgradeneeded = (/** * @param {?} event * @return {?} */ function (event) { observer.next({ upgraded: true, success: true, result: DBOpenRequest.result }); observer.complete(); upgraded = true; }); DBOpenRequest.onsuccess = (/** * @param {?} event * @return {?} */ function (event) { if (!upgraded) { observer.next({ upgraded: false, success: true, result: DBOpenRequest.result }); observer.complete(); } }); DBOpenRequest.onerror = (/** * @param {?} event * @return {?} */ function (event) { observer.error("Error to connect database " + dbName); observer.complete(); }); DBOpenRequest.onblocked = (/** * @param {?} event * @return {?} */ function (event) { console.log('blocked'); }); })); }; /** * Generates an Observable collection of database connections * @param Databases metadata */ /** * Generates an Observable collection of database connections * @param {?} databases * @return {?} */ NgDatabaseFactory.prototype.createDataBases = /** * Generates an Observable collection of database connections * @param {?} databases * @return {?} */ function (databases) { var _this = this; /** @type {?} */ var operators = []; /** @type {?} */ var firstIteration = true; /** @type {?} */ var createConnnection = (/** * @param {?} item * @return {?} */ function (item) { if (firstIteration) { _this.defaultConnectionName = item.name; firstIteration = false; } operators.push(_this.createConnection(item.name, item.stores, 1)); }); databases.forEach(createConnnection); /** @type {?} */ var mappingResponse = (/** * @param {?} response * @return {?} */ function (response) { /** @type {?} */ var data = {}; response.forEach((/** * @param {?} item * @return {?} */ function (item) { data = __assign({}, data, item); })); return data; }); return forkJoin(operators) .pipe(map(mappingResponse)); }; /** * Generates a sigle database conecction client */ /** * Generates a sigle database conecction client * @private * @param {?} dbName * @param {?} tables * @param {?=} version * @return {?} */ NgDatabaseFactory.prototype.createConnection = /** * Generates a sigle database conecction client * @private * @param {?} dbName * @param {?} tables * @param {?=} version * @return {?} */ function (dbName, tables, version) { return this.open(dbName, version) .pipe(map((/** * @param {?} data * @return {?} */ function (data) { var _a; return (_a = {}, _a[dbName] = new IndexedDatabase(data.result, data.upgraded, tables), _a); }))); }; NgDatabaseFactory.decorators = [ { type: Injectable } ]; return NgDatabaseFactory; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ var IdGenerator = /** @class */ (function () { function IdGenerator() { } /** * @param {?=} data * @return {?} */ IdGenerator.prototype.generate = /** * @param {?=} data * @return {?} */ function (data) { return (new Date()).getTime(); }; IdGenerator.decorators = [ { type: Injectable } ]; return IdGenerator; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Injection token that gives the databases metadata * @type {?} */ var NG_DATABASES = new InjectionToken('NG_DATABASES'); /** * Service that handles all Indexed Databases and * tables requests. */ var IndexedDB = /** @class */ (function () { function IndexedDB(databases, idGenerator, databaseFactory) { this.databases = databases; this.idGenerator = idGenerator; this.databaseFactory = databaseFactory; this.databaseFactory.createConnnections(this.databases); } Object.defineProperty(IndexedDB.prototype, "onReady", { /** * Indicates if all databases have been created. * Only emits an event when recives a true value. */ get: /** * Indicates if all databases have been created. * Only emits an event when recives a true value. * @return {?} */ function () { return this.databaseFactory.connectionsReady .pipe(skipWhile((/** * @param {?} event * @return {?} */ function (event) { return !event; }))); }, enumerable: true, configurable: true }); /** * Request a list with all elements * @param storeName Store name * @param databaseName Database name */ /** * Request a list with all elements * @template M * @param {?} storeName Store name * @param {?=} databaseName Database name * @return {?} */ IndexedDB.prototype.list = /** * Request a list with all elements * @template M * @param {?} storeName Store name * @param {?=} databaseName Database name * @return {?} */ function (storeName, databaseName) { var _this = this; return this.onReady.pipe(switchMap((/** * @return {?} */ function () { return _this.databaseFactory.getDatabase(databaseName).list(storeName); }))); }; /** * Request an element by key * @param storeName Store name * @param key Key value to find the element * @param databaseName Database name */ /** * Request an element by key * @template M * @param {?} storeName Store name * @param {?} key Key value to find the element * @param {?=} databaseName Database name * @return {?} */ IndexedDB.prototype.get = /** * Request an element by key * @template M * @param {?} storeName Store name * @param {?} key Key value to find the element * @param {?=} databaseName Database name * @return {?} */ function (storeName, key, databaseName) { var _this = this; return this.onReady.pipe(switchMap((/** * @return {?} */ function () { return _this.databaseFactory.getDatabase(databaseName).get(storeName, key); }))); }; /** * Request to store an element * @param storeName Store name * @param databaseName Database name */ /** * Request to store an element * @template M * @param {?} storeName Store name * @param {?} data * @param {?=} databaseName Database name * @return {?} */ IndexedDB.prototype.create = /** * Request to store an element * @template M * @param {?} storeName Store name * @param {?} data * @param {?=} databaseName Database name * @return {?} */ function (storeName, data, databaseName) { var _this = this; // tslint:disable-next-line: no-string-literal if (!data['id']) { data['id'] = this.idGenerator.generate(); } return this.onReady.pipe(switchMap((/** * @return {?} */ function () { return _this.databaseFactory.getDatabase(databaseName).create(storeName, data); }))); }; /** * Request to update a stored element * @param storeName Store name * @param databaseName Database name */ /** * Request to update a stored element * @template M * @param {?} storeName Store name * @param {?} data * @param {?=} databaseName Database name * @return {?} */ IndexedDB.prototype.update = /** * Request to update a stored element * @template M * @param {?} storeName Store name * @param {?} data * @param {?=} databaseName Database name * @return {?} */ function (storeName, data, databaseName) { var _this = this; return this.onReady.pipe(switchMap((/** * @return {?} */ function () { return _this.databaseFactory.getDatabase(databaseName).update(storeName, data); }))); }; /** * Request to delete a stored element * @param storeName Store name * @param databaseName Database name */ /** * Request to delete a stored element * @param {?} storeName Store name * @param {?} key * @param {?=} databaseName Database name * @return {?} */ IndexedDB.prototype.delete = /** * Request to delete a stored element * @param {?} storeName Store name * @param {?} key * @param {?=} databaseName Database name * @return {?} */ function (storeName, key, databaseName) { var _this = this; return this.onReady.pipe(switchMap((/** * @return {?} */ function () { return _this.databaseFactory.getDatabase(databaseName).delete(storeName, key); }))); }; IndexedDB.decorators = [ { type: Injectable } ]; /** @nocollapse */ IndexedDB.ctorParameters = function () { return [ { type: Array, decorators: [{ type: Inject, args: [NG_DATABASES,] }] }, { type: IdGenerator }, { type: NgDatabaseFactory } ]; }; return IndexedDB; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ var IndexedDBModule = /** @class */ (function () { function IndexedDBModule() { } /** * @param {?=} databases * @return {?} */ IndexedDBModule.forRoot = /** * @param {?=} databases * @return {?} */ function (databases) { if (databases === void 0) { databases = []; } return { ngModule: IndexedDBModule, providers: [ { provide: NG_DATABASES, useValue: databases } ] }; }; IndexedDBModule.decorators = [ { type: NgModule, args: [{ declarations: [], imports: [CommonModule], exports: [], providers: [ IndexedDB, NgDatabaseFactory, IdGenerator, ], },] } ]; return IndexedDBModule; }()); export { IndexedDB, IndexedDBModule, NG_DATABASES, IdGenerator as ɵb, NgDatabaseFactory as ɵc }; //# sourceMappingURL=ng-indexed-db.js.map