ng-indexed-db
Version:
An IndexedDB Angular module wrapped in RXJS
804 lines (796 loc) • 24.1 kB
JavaScript
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