angular-async-local-storage
Advanced tools
Comparing version 3.1.4 to 4.0.0
@@ -5,2 +5,3 @@ /** | ||
export * from './index'; | ||
export { databaseFactory as ɵa } from './src/module'; | ||
export { asyncLocalStorageFactory as ɵa } from './src/module'; | ||
export { AsyncLocalDatabase as ɵb } from './src/service/databases/async-local-database'; |
import { Injectable, NgModule, PLATFORM_ID } from '@angular/core'; | ||
import { isPlatformBrowser } from '@angular/common'; | ||
import { Observable } from 'rxjs/Observable'; | ||
import { ReplaySubject } from 'rxjs/ReplaySubject'; | ||
import { first, map, mergeMap } from 'rxjs/operators'; | ||
import { fromEvent } from 'rxjs/observable/fromEvent'; | ||
import { of } from 'rxjs/observable/of'; | ||
import { _throw } from 'rxjs/observable/throw'; | ||
import { race } from 'rxjs/observable/race'; | ||
import { isPlatformBrowser } from '@angular/common'; | ||
import 'rxjs/add/operator/map'; | ||
import 'rxjs/add/operator/mergeMap'; | ||
import 'rxjs/add/operator/pluck'; | ||
import 'rxjs/add/operator/first'; | ||
import 'rxjs/add/observable/fromEvent'; | ||
import 'rxjs/add/observable/merge'; | ||
import 'rxjs/add/observable/throw'; | ||
import 'rxjs/add/observable/of'; | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
*/ | ||
/** | ||
* @abstract | ||
@@ -20,5 +20,83 @@ */ | ||
} | ||
/** | ||
* @abstract | ||
* @template T | ||
* @param {?} key | ||
* @return {?} | ||
*/ | ||
AsyncLocalDatabase.prototype.getItem = function (key) { }; | ||
/** | ||
* @abstract | ||
* @param {?} key | ||
* @param {?} data | ||
* @return {?} | ||
*/ | ||
AsyncLocalDatabase.prototype.setItem = function (key, data) { }; | ||
/** | ||
* @abstract | ||
* @param {?} key | ||
* @return {?} | ||
*/ | ||
AsyncLocalDatabase.prototype.removeItem = function (key) { }; | ||
/** | ||
* @abstract | ||
* @return {?} | ||
*/ | ||
AsyncLocalDatabase.prototype.clear = function () { }; | ||
return AsyncLocalDatabase; | ||
}()); | ||
var AsyncLocalStorage = (function () { | ||
/** | ||
* Injects a local database | ||
* @param {?} database | ||
*/ | ||
function AsyncLocalStorage(database) { | ||
this.database = database; | ||
} | ||
/** | ||
* Gets an item value in local storage | ||
* @template T | ||
* @param {?} key The item's key | ||
* @return {?} The item's value if the key exists, null otherwise, wrapped in an RxJS Observable | ||
*/ | ||
AsyncLocalStorage.prototype.getItem = function (key) { | ||
return this.database.getItem(key); | ||
}; | ||
/** | ||
* Sets an item in local storage | ||
* @param {?} key The item's key | ||
* @param {?} data The item's value, must NOT be null or undefined | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
AsyncLocalStorage.prototype.setItem = function (key, data) { | ||
return this.database.setItem(key, data); | ||
}; | ||
/** | ||
* Deletes an item in local storage | ||
* @param {?} key The item's key | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
AsyncLocalStorage.prototype.removeItem = function (key) { | ||
return this.database.removeItem(key); | ||
}; | ||
/** | ||
* Deletes all items from local storage | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
AsyncLocalStorage.prototype.clear = function () { | ||
return this.database.clear(); | ||
}; | ||
return AsyncLocalStorage; | ||
}()); | ||
AsyncLocalStorage.decorators = [ | ||
{ type: Injectable }, | ||
]; | ||
/** | ||
* @nocollapse | ||
*/ | ||
AsyncLocalStorage.ctorParameters = function () { return [ | ||
{ type: AsyncLocalDatabase, }, | ||
]; }; | ||
var __extends = (undefined && undefined.__extends) || (function () { | ||
@@ -34,6 +112,2 @@ var extendStatics = Object.setPrototypeOf || | ||
})(); | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
*/ | ||
var IndexedDBDatabase = (function (_super) { | ||
@@ -63,6 +137,4 @@ __extends(IndexedDBDatabase, _super); | ||
/* Creating the RxJS ReplaySubject */ | ||
/* Creating the RxJS ReplaySubject */ | ||
_this.database = new ReplaySubject(); | ||
/* Connecting to IndexedDB */ | ||
/* Connecting to IndexedDB */ | ||
_this.connect(); | ||
@@ -73,7 +145,2 @@ return _this; | ||
* Gets an item value in local storage | ||
* @param key The item's key | ||
* @returns The item's value if the key exists, null otherwise, wrapped in an RxJS Observable | ||
*/ | ||
/** | ||
* Gets an item value in local storage | ||
* @template T | ||
@@ -83,27 +150,16 @@ * @param {?} key The item's key | ||
*/ | ||
IndexedDBDatabase.prototype.getItem = /** | ||
* Gets an item value in local storage | ||
* @template T | ||
* @param {?} key The item's key | ||
* @return {?} The item's value if the key exists, null otherwise, wrapped in an RxJS Observable | ||
*/ | ||
function (key) { | ||
IndexedDBDatabase.prototype.getItem = function (key) { | ||
var _this = this; | ||
/* Opening a trasaction and requesting the item in local storage */ | ||
return this.transaction().pipe(map(function (transaction) { return transaction.get(key); }), mergeMap(function (request) { | ||
return this.transaction().map(function (transaction) { return transaction.get(key); }).mergeMap(function (request) { | ||
/* Listening to the success event, and passing the item value if found, null otherwise */ | ||
var /** @type {?} */ success = (/** @type {?} */ (fromEvent(request, 'success'))).pipe(map(function (event) { return (/** @type {?} */ (event.target)).result; }), map(function (result) { return result && (_this.dataPath in result) ? (/** @type {?} */ (result[_this.dataPath])) : null; })); | ||
var /** @type {?} */ success = Observable.fromEvent(request, 'success') | ||
.pluck('target', 'result') | ||
.map(function (result) { return result ? result[_this.dataPath] : null; }); | ||
/* Merging success and errors events and autoclosing the observable */ | ||
return (/** @type {?} */ (race(success, _this.toErrorObservable(request, "getter")))) | ||
.pipe(first()); | ||
}), first()); | ||
return Observable.merge(success, _this.toErrorObservable(request, "getter")).first(); | ||
}).first(); | ||
}; | ||
/** | ||
* Sets an item in local storage | ||
* @param key The item's key | ||
* @param data The item's value, must NOT be null or undefined | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Sets an item in local storage | ||
* @param {?} key The item's key | ||
@@ -113,18 +169,12 @@ * @param {?} data The item's value, must NOT be null or undefined | ||
*/ | ||
IndexedDBDatabase.prototype.setItem = /** | ||
* Sets an item in local storage | ||
* @param {?} key The item's key | ||
* @param {?} data The item's value, must NOT be null or undefined | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function (key, data) { | ||
IndexedDBDatabase.prototype.setItem = function (key, data) { | ||
var _this = this; | ||
/* Storing null is not correctly supported by IndexedDB and unnecessary here */ | ||
if (data == null) { | ||
return of(true); | ||
return Observable.of(true).first(); | ||
} | ||
/* Opening a transaction and checking if the item already exists in local storage */ | ||
return this.getItem(key).pipe(map(function (existingData) { return (existingData == null) ? 'add' : 'put'; }), mergeMap(function (method) { | ||
return this.getItem(key).map(function (existingData) { return (existingData == null) ? 'add' : 'put'; }).mergeMap(function (method) { | ||
/* Opening a transaction */ | ||
return _this.transaction('readwrite').pipe(mergeMap(function (transaction) { | ||
return _this.transaction('readwrite').mergeMap(function (transaction) { | ||
var /** @type {?} */ request; | ||
@@ -142,77 +192,49 @@ /* Adding or updating local storage, based on previous checking */ | ||
/* Merging success (passing true) and error events and autoclosing the observable */ | ||
return (/** @type {?} */ (race(_this.toSuccessObservable(request), _this.toErrorObservable(request, "setter")))) | ||
.pipe(first()); | ||
return Observable.merge(_this.toSuccessObservable(request), _this.toErrorObservable(request, "setter")).first(); | ||
var _a, _b; | ||
})); | ||
}), first()); | ||
}); | ||
}).first(); | ||
}; | ||
/** | ||
* Deletes an item in local storage | ||
* @param key The item's key | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Deletes an item in local storage | ||
* @param {?} key The item's key | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
IndexedDBDatabase.prototype.removeItem = /** | ||
* Deletes an item in local storage | ||
* @param {?} key The item's key | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function (key) { | ||
IndexedDBDatabase.prototype.removeItem = function (key) { | ||
var _this = this; | ||
/* Opening a transaction and checking if the item exists in local storage */ | ||
return this.getItem(key).pipe(mergeMap(function (data) { | ||
return this.getItem(key).mergeMap(function (data) { | ||
/* If the item exists in local storage */ | ||
if (data != null) { | ||
/* Opening a transaction */ | ||
return _this.transaction('readwrite').pipe(mergeMap(function (transaction) { | ||
return _this.transaction('readwrite').mergeMap(function (transaction) { | ||
/* Deleting the item in local storage */ | ||
var /** @type {?} */ request = transaction.delete(key); | ||
/* Merging success (passing true) and error events and autoclosing the observable */ | ||
return (/** @type {?} */ (race(_this.toSuccessObservable(request), _this.toErrorObservable(request, "remover")))) | ||
.pipe(first()); | ||
})); | ||
return Observable.merge(_this.toSuccessObservable(request), _this.toErrorObservable(request, "remover")).first(); | ||
}); | ||
} | ||
/* Passing true if the item does not exist in local storage */ | ||
return of(true); | ||
}), first()); | ||
return Observable.of(true).first(); | ||
}).first(); | ||
}; | ||
/** | ||
* Deletes all items from local storage | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Deletes all items from local storage | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
IndexedDBDatabase.prototype.clear = /** | ||
* Deletes all items from local storage | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function () { | ||
IndexedDBDatabase.prototype.clear = function () { | ||
var _this = this; | ||
/* Opening a transaction */ | ||
return this.transaction('readwrite').pipe(mergeMap(function (transaction) { | ||
return this.transaction('readwrite').mergeMap(function (transaction) { | ||
/* Deleting all items from local storage */ | ||
var /** @type {?} */ request = transaction.clear(); | ||
/* Merging success (passing true) and error events and autoclosing the observable */ | ||
return (/** @type {?} */ (race(_this.toSuccessObservable(request), _this.toErrorObservable(request, "clearer")))) | ||
.pipe(first()); | ||
}), first()); | ||
return Observable.merge(_this.toSuccessObservable(request), _this.toErrorObservable(request, "clearer")).first(); | ||
}).first(); | ||
}; | ||
/** | ||
* Connects to IndexedDB and creates the object store on first time | ||
*/ | ||
/** | ||
* Connects to IndexedDB and creates the object store on first time | ||
* @return {?} | ||
*/ | ||
IndexedDBDatabase.prototype.connect = /** | ||
* Connects to IndexedDB and creates the object store on first time | ||
* @return {?} | ||
*/ | ||
function () { | ||
IndexedDBDatabase.prototype.connect = function () { | ||
var _this = this; | ||
@@ -222,7 +244,5 @@ /* Connecting to IndexedDB */ | ||
/* Listening the event fired on first connection, creating the object store for local storage */ | ||
(/** @type {?} */ (fromEvent(request, 'upgradeneeded'))) | ||
.pipe(first()) | ||
.subscribe(function (event) { | ||
Observable.fromEvent(request, 'upgradeneeded').first().subscribe(function (event) { | ||
/* Getting the database connection */ | ||
var /** @type {?} */ database = /** @type {?} */ ((/** @type {?} */ (event.target)).result); | ||
var /** @type {?} */ database = (((event.target)).result); | ||
/* Checking if the object store already exists, to avoid error */ | ||
@@ -235,10 +255,7 @@ if (!database.objectStoreNames.contains(_this.objectStoreName)) { | ||
/* Listening the success event and converting to an RxJS Observable */ | ||
var /** @type {?} */ success = /** @type {?} */ (fromEvent(request, 'success')); | ||
var /** @type {?} */ success = Observable.fromEvent(request, 'success'); | ||
/* Merging success and errors events */ | ||
(/** @type {?} */ (race(success, this.toErrorObservable(request, "connection")))) | ||
.pipe(first()) | ||
.subscribe(function (event) { | ||
Observable.merge(success, this.toErrorObservable(request, "connection")).first().subscribe(function (event) { | ||
/* Storing the database connection for further access */ | ||
/* Storing the database connection for further access */ | ||
_this.database.next(/** @type {?} */ ((/** @type {?} */ (event.target)).result)); | ||
_this.database.next(/** @type {?} */ (((event.target)).result)); | ||
}, function (error) { | ||
@@ -250,50 +267,22 @@ _this.database.error(/** @type {?} */ (error)); | ||
* Opens an IndexedDB transaction and gets the local storage object store | ||
* @param mode Default to 'readonly' for read operations, or 'readwrite' for write operations | ||
* @returns An IndexedDB transaction object store, wrapped in an RxJS Observable | ||
*/ | ||
/** | ||
* Opens an IndexedDB transaction and gets the local storage object store | ||
* @param {?=} mode Default to 'readonly' for read operations, or 'readwrite' for write operations | ||
* @return {?} An IndexedDB transaction object store, wrapped in an RxJS Observable | ||
*/ | ||
IndexedDBDatabase.prototype.transaction = /** | ||
* Opens an IndexedDB transaction and gets the local storage object store | ||
* @param {?=} mode Default to 'readonly' for read operations, or 'readwrite' for write operations | ||
* @return {?} An IndexedDB transaction object store, wrapped in an RxJS Observable | ||
*/ | ||
function (mode) { | ||
IndexedDBDatabase.prototype.transaction = function (mode) { | ||
var _this = this; | ||
if (mode === void 0) { mode = 'readonly'; } | ||
/* From the IndexedDB connection, opening a transaction and getting the local storage objet store */ | ||
return this.database | ||
.pipe(map(function (database) { return database.transaction([_this.objectStoreName], mode).objectStore(_this.objectStoreName); })); | ||
return this.database.map(function (database) { return database.transaction([_this.objectStoreName], mode).objectStore(_this.objectStoreName); }); | ||
}; | ||
/** | ||
* Transforms a IndexedDB success event in an RxJS Observable | ||
* @param request The request to listen | ||
* @returns A RxJS Observable with true value | ||
*/ | ||
/** | ||
* Transforms a IndexedDB success event in an RxJS Observable | ||
* @param {?} request The request to listen | ||
* @return {?} A RxJS Observable with true value | ||
*/ | ||
IndexedDBDatabase.prototype.toSuccessObservable = /** | ||
* Transforms a IndexedDB success event in an RxJS Observable | ||
* @param {?} request The request to listen | ||
* @return {?} A RxJS Observable with true value | ||
*/ | ||
function (request) { | ||
IndexedDBDatabase.prototype.toSuccessObservable = function (request) { | ||
/* Transforming a IndexedDB success event in an RxJS Observable with true value */ | ||
return (/** @type {?} */ (fromEvent(request, 'success'))) | ||
.pipe(map(function () { return true; })); | ||
return Observable.fromEvent(request, 'success').map(function () { return true; }); | ||
}; | ||
/** | ||
* Transforms a IndexedDB error event in an RxJS ErrorObservable | ||
* @param request The request to listen | ||
* @param error Optionnal details about the error's origin | ||
* @returns A RxJS ErrorObservable | ||
*/ | ||
/** | ||
* Transforms a IndexedDB error event in an RxJS ErrorObservable | ||
* @param {?} request The request to listen | ||
@@ -303,21 +292,16 @@ * @param {?=} error Optionnal details about the error's origin | ||
*/ | ||
IndexedDBDatabase.prototype.toErrorObservable = /** | ||
* Transforms a IndexedDB error event in an RxJS ErrorObservable | ||
* @param {?} request The request to listen | ||
* @param {?=} error Optionnal details about the error's origin | ||
* @return {?} A RxJS ErrorObservable | ||
*/ | ||
function (request, error) { | ||
IndexedDBDatabase.prototype.toErrorObservable = function (request, error) { | ||
if (error === void 0) { error = ""; } | ||
/* Transforming a IndexedDB error event in an RxJS ErrorObservable */ | ||
return (/** @type {?} */ (fromEvent(request, 'error'))) | ||
.pipe(mergeMap(function (event) { return _throw(new Error("IndexedDB " + error + " issue : " + request.error.message + ".")); })); | ||
return Observable.fromEvent(request, 'error').mergeMap(function () { return Observable.throw(new Error("IndexedDB " + error + " issue.")); }); | ||
}; | ||
IndexedDBDatabase.decorators = [ | ||
{ type: Injectable }, | ||
]; | ||
/** @nocollapse */ | ||
IndexedDBDatabase.ctorParameters = function () { return []; }; | ||
return IndexedDBDatabase; | ||
}(AsyncLocalDatabase)); | ||
IndexedDBDatabase.decorators = [ | ||
{ type: Injectable }, | ||
]; | ||
/** | ||
* @nocollapse | ||
*/ | ||
IndexedDBDatabase.ctorParameters = function () { return []; }; | ||
@@ -334,6 +318,2 @@ var __extends$1 = (undefined && undefined.__extends) || (function () { | ||
})(); | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
*/ | ||
var LocalStorageDatabase = (function (_super) { | ||
@@ -349,7 +329,2 @@ __extends$1(LocalStorageDatabase, _super); | ||
* Gets an item value in local storage | ||
* @param key The item's key | ||
* @returns The item's value if the key exists, null otherwise, wrapped in an RxJS Observable | ||
*/ | ||
/** | ||
* Gets an item value in local storage | ||
* @template T | ||
@@ -359,29 +334,16 @@ * @param {?} key The item's key | ||
*/ | ||
LocalStorageDatabase.prototype.getItem = /** | ||
* Gets an item value in local storage | ||
* @template T | ||
* @param {?} key The item's key | ||
* @return {?} The item's value if the key exists, null otherwise, wrapped in an RxJS Observable | ||
*/ | ||
function (key) { | ||
var /** @type {?} */ unparsedData = this.localStorage.getItem(key); | ||
var /** @type {?} */ parsedData = null; | ||
if (unparsedData != null) { | ||
LocalStorageDatabase.prototype.getItem = function (key) { | ||
var /** @type {?} */ data = this.localStorage.getItem(key); | ||
if (data != null) { | ||
try { | ||
parsedData = JSON.parse(unparsedData); | ||
data = JSON.parse(data); | ||
} | ||
catch (/** @type {?} */ error) { | ||
return _throw(new Error("Invalid data in localStorage.")); | ||
catch (error) { | ||
return Observable.throw(new Error("Invalid data in localStorage.")); | ||
} | ||
} | ||
return of(parsedData); | ||
return Observable.of(data); | ||
}; | ||
/** | ||
* Sets an item in local storage | ||
* @param key The item's key | ||
* @param data The item's value, must NOT be null or undefined | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Sets an item in local storage | ||
* @param {?} key The item's key | ||
@@ -391,54 +353,32 @@ * @param {?} data The item's value, must NOT be null or undefined | ||
*/ | ||
LocalStorageDatabase.prototype.setItem = /** | ||
* Sets an item in local storage | ||
* @param {?} key The item's key | ||
* @param {?} data The item's value, must NOT be null or undefined | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function (key, data) { | ||
LocalStorageDatabase.prototype.setItem = function (key, data) { | ||
this.localStorage.setItem(key, JSON.stringify(data)); | ||
return of(true); | ||
return Observable.of(true); | ||
}; | ||
/** | ||
* Deletes an item in local storage | ||
* @param key The item's key | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Deletes an item in local storage | ||
* @param {?} key The item's key | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
LocalStorageDatabase.prototype.removeItem = /** | ||
* Deletes an item in local storage | ||
* @param {?} key The item's key | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function (key) { | ||
LocalStorageDatabase.prototype.removeItem = function (key) { | ||
this.localStorage.removeItem(key); | ||
return of(true); | ||
return Observable.of(true); | ||
}; | ||
/** | ||
* Deletes all items from local storage | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Deletes all items from local storage | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
LocalStorageDatabase.prototype.clear = /** | ||
* Deletes all items from local storage | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function () { | ||
LocalStorageDatabase.prototype.clear = function () { | ||
this.localStorage.clear(); | ||
return of(true); | ||
return Observable.of(true); | ||
}; | ||
LocalStorageDatabase.decorators = [ | ||
{ type: Injectable }, | ||
]; | ||
/** @nocollapse */ | ||
LocalStorageDatabase.ctorParameters = function () { return []; }; | ||
return LocalStorageDatabase; | ||
}(AsyncLocalDatabase)); | ||
LocalStorageDatabase.decorators = [ | ||
{ type: Injectable }, | ||
]; | ||
/** | ||
* @nocollapse | ||
*/ | ||
LocalStorageDatabase.ctorParameters = function () { return []; }; | ||
@@ -455,6 +395,2 @@ var __extends$2 = (undefined && undefined.__extends) || (function () { | ||
})(); | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
*/ | ||
var MockLocalDatabase = (function (_super) { | ||
@@ -469,7 +405,2 @@ __extends$2(MockLocalDatabase, _super); | ||
* Gets an item value in local storage | ||
* @param key The item's key | ||
* @returns The item's value if the key exists, null otherwise, wrapped in an RxJS Observable | ||
*/ | ||
/** | ||
* Gets an item value in local storage | ||
* @template T | ||
@@ -479,20 +410,8 @@ * @param {?} key The item's key | ||
*/ | ||
MockLocalDatabase.prototype.getItem = /** | ||
* Gets an item value in local storage | ||
* @template T | ||
* @param {?} key The item's key | ||
* @return {?} The item's value if the key exists, null otherwise, wrapped in an RxJS Observable | ||
*/ | ||
function (key) { | ||
var /** @type {?} */ rawData = this.localStorage.get(key); | ||
return of((rawData !== undefined) ? rawData : null); | ||
MockLocalDatabase.prototype.getItem = function (key) { | ||
var /** @type {?} */ data = this.localStorage.get(key); | ||
return Observable.of((data !== undefined) ? data : null); | ||
}; | ||
/** | ||
* Sets an item in local storage | ||
* @param key The item's key | ||
* @param data The item's value, must NOT be null or undefined | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Sets an item in local storage | ||
* @param {?} key The item's key | ||
@@ -502,463 +421,80 @@ * @param {?} data The item's value, must NOT be null or undefined | ||
*/ | ||
MockLocalDatabase.prototype.setItem = /** | ||
* Sets an item in local storage | ||
* @param {?} key The item's key | ||
* @param {?} data The item's value, must NOT be null or undefined | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function (key, data) { | ||
MockLocalDatabase.prototype.setItem = function (key, data) { | ||
this.localStorage.set(key, data); | ||
return of(true); | ||
return Observable.of(true); | ||
}; | ||
/** | ||
* Deletes an item in local storage | ||
* @param key The item's key | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Deletes an item in local storage | ||
* @param {?} key The item's key | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
MockLocalDatabase.prototype.removeItem = /** | ||
* Deletes an item in local storage | ||
* @param {?} key The item's key | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function (key) { | ||
MockLocalDatabase.prototype.removeItem = function (key) { | ||
this.localStorage.delete(key); | ||
return of(true); | ||
return Observable.of(true); | ||
}; | ||
/** | ||
* Deletes all items from local storage | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Deletes all items from local storage | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
MockLocalDatabase.prototype.clear = /** | ||
* Deletes all items from local storage | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function () { | ||
MockLocalDatabase.prototype.clear = function () { | ||
this.localStorage.clear(); | ||
return of(true); | ||
return Observable.of(true); | ||
}; | ||
MockLocalDatabase.decorators = [ | ||
{ type: Injectable }, | ||
]; | ||
/** @nocollapse */ | ||
MockLocalDatabase.ctorParameters = function () { return []; }; | ||
return MockLocalDatabase; | ||
}(AsyncLocalDatabase)); | ||
MockLocalDatabase.decorators = [ | ||
{ type: Injectable }, | ||
]; | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
* @nocollapse | ||
*/ | ||
/** | ||
* \@todo Add other JSON Schema validation features | ||
*/ | ||
var JSONValidator = (function () { | ||
function JSONValidator() { | ||
this.simpleTypes = ['string', 'number', 'boolean', 'object']; | ||
} | ||
/** | ||
* @param {?} value | ||
* @return {?} | ||
*/ | ||
JSONValidator.prototype.isObjectNotNull = /** | ||
* @param {?} value | ||
* @return {?} | ||
*/ | ||
function (value) { | ||
return (value !== null) && (typeof value === 'object'); | ||
}; | ||
/** | ||
* Validate a JSON data against a JSON Schema | ||
* @param data JSON data to validate | ||
* @param schema Subset of JSON Schema | ||
* @returns If data is valid : true, if it is invalid : false, and throws if the schema is invalid | ||
*/ | ||
/** | ||
* Validate a JSON data against a JSON Schema | ||
* @param {?} data JSON data to validate | ||
* @param {?} schema Subset of JSON Schema | ||
* @return {?} If data is valid : true, if it is invalid : false, and throws if the schema is invalid | ||
*/ | ||
JSONValidator.prototype.validate = /** | ||
* Validate a JSON data against a JSON Schema | ||
* @param {?} data JSON data to validate | ||
* @param {?} schema Subset of JSON Schema | ||
* @return {?} If data is valid : true, if it is invalid : false, and throws if the schema is invalid | ||
*/ | ||
function (data, schema) { | ||
if (!this.isObjectNotNull(schema)) { | ||
throw new Error("A schema must be an object (unlike spec, booleans are not supported to enforce strict types)."); | ||
} | ||
if ((!schema.hasOwnProperty('type') || schema.type === 'array' || schema.type === 'object') | ||
&& !schema.hasOwnProperty('properties') && !schema.hasOwnProperty('items')) { | ||
throw new Error("Each value must have a 'type' or 'properties' or 'items', to enforce strict types."); | ||
} | ||
if (schema.hasOwnProperty('type') && !this.validateType(data, schema)) { | ||
return false; | ||
} | ||
if (schema.hasOwnProperty('items') && !this.validateItems(data, schema)) { | ||
return false; | ||
} | ||
if (schema.hasOwnProperty('properties')) { | ||
if (schema.hasOwnProperty('required') && !this.validateRequired(data, schema)) { | ||
return false; | ||
} | ||
if (!this.validateProperties(data, schema)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
}; | ||
/** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
JSONValidator.prototype.validateProperties = /** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
function (data, schema) { | ||
if (!this.isObjectNotNull(data)) { | ||
return false; | ||
} | ||
if (!schema.properties || !this.isObjectNotNull(schema.properties)) { | ||
throw new Error("'properties' must be a schema object."); | ||
} | ||
/** | ||
* Check if the object doesn't have more properties than expected | ||
* Equivalent of additionalProperties: false | ||
*/ | ||
if (Object.keys(schema.properties).length !== Object.keys(data).length) { | ||
return false; | ||
} | ||
/* Recursively validate all properties */ | ||
for (var /** @type {?} */ property in schema.properties) { | ||
if (schema.properties.hasOwnProperty(property) && data.hasOwnProperty(property)) { | ||
if (!this.validate(data[property], schema.properties[property])) { | ||
return false; | ||
} | ||
} | ||
} | ||
return true; | ||
}; | ||
/** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
JSONValidator.prototype.validateRequired = /** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
function (data, schema) { | ||
if (!this.isObjectNotNull(data)) { | ||
return false; | ||
} | ||
if (!Array.isArray(schema.required)) { | ||
throw new Error("'required' field must be an array. Note that since JSON Schema draft 6, booleans are not supported anymore."); | ||
} | ||
for (var _i = 0, _a = schema.required; _i < _a.length; _i++) { | ||
var requiredProp = _a[_i]; | ||
if (typeof requiredProp !== 'string') { | ||
throw new Error("'required' array must contain strings only."); | ||
} | ||
/* Checks if the property is present in the schema 'properties' */ | ||
if (!schema.properties || !schema.properties.hasOwnProperty(requiredProp)) { | ||
throw new Error("'required' properties must be described in 'properties' too."); | ||
} | ||
/* Checks if the property is present in the data */ | ||
if (!data.hasOwnProperty(requiredProp)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
}; | ||
/** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
JSONValidator.prototype.validateType = /** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
function (data, schema) { | ||
if (Array.isArray(schema.type)) { | ||
return this.validateTypeList(data, schema); | ||
} | ||
if (typeof schema.type !== 'string') { | ||
throw new Error("'type' must be a string (arrays of types are not supported yet)."); | ||
} | ||
if ((schema.type === 'null') && (data !== null)) { | ||
return false; | ||
} | ||
if ((this.simpleTypes.indexOf(schema.type) !== -1) && (typeof data !== schema.type)) { | ||
return false; | ||
} | ||
if ((schema.type === 'integer') && ((typeof data !== 'number') || !Number.isInteger(data))) { | ||
return false; | ||
} | ||
return true; | ||
}; | ||
/** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
JSONValidator.prototype.validateTypeList = /** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
function (data, schema) { | ||
var /** @type {?} */ types = /** @type {?} */ (schema.type); | ||
var /** @type {?} */ typesTests = []; | ||
for (var _i = 0, types_1 = types; _i < types_1.length; _i++) { | ||
var type = types_1[_i]; | ||
typesTests.push(this.validateType(data, { type: type })); | ||
} | ||
return (typesTests.indexOf(true) !== -1); | ||
}; | ||
/** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
JSONValidator.prototype.validateItems = /** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
function (data, schema) { | ||
if (!Array.isArray(data)) { | ||
return false; | ||
} | ||
if (Array.isArray(schema.items)) { | ||
return this.validateItemsList(data, schema); | ||
} | ||
if (!schema.items || !this.isObjectNotNull(schema.items)) { | ||
throw new Error("'items' must be a schema object."); | ||
} | ||
for (var _i = 0, data_1 = data; _i < data_1.length; _i++) { | ||
var value = data_1[_i]; | ||
if (!this.validate(value, schema.items)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
}; | ||
/** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
JSONValidator.prototype.validateItemsList = /** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
function (data, schema) { | ||
var /** @type {?} */ items = /** @type {?} */ (schema.items); | ||
if (data.length !== items.length) { | ||
return false; | ||
} | ||
for (var /** @type {?} */ i = 0; i < items.length; i += 1) { | ||
if (!this.validate(data[i], items[i])) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
}; | ||
return JSONValidator; | ||
}()); | ||
MockLocalDatabase.ctorParameters = function () { return []; }; | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
*/ | ||
/** | ||
* @record | ||
*/ | ||
var AsyncLocalStorage = (function () { | ||
function AsyncLocalStorage(database, jsonValidator) { | ||
this.database = database; | ||
this.jsonValidator = jsonValidator; | ||
this.getItemOptionsDefault = { | ||
schema: null | ||
}; | ||
} | ||
/** | ||
* Gets an item value in local storage | ||
* @param key The item's key | ||
* @returns The item's value if the key exists, null otherwise, wrapped in an RxJS Observable | ||
*/ | ||
/** | ||
* Gets an item value in local storage | ||
* @template T | ||
* @param {?} key The item's key | ||
* @param {?=} options | ||
* @return {?} The item's value if the key exists, null otherwise, wrapped in an RxJS Observable | ||
*/ | ||
AsyncLocalStorage.prototype.getItem = /** | ||
* Gets an item value in local storage | ||
* @template T | ||
* @param {?} key The item's key | ||
* @param {?=} options | ||
* @return {?} The item's value if the key exists, null otherwise, wrapped in an RxJS Observable | ||
*/ | ||
function (key, options) { | ||
var _this = this; | ||
if (options === void 0) { options = this.getItemOptionsDefault; } | ||
return this.database.getItem(key).pipe(/* Validate data upon a json schema if requested */ | ||
mergeMap(function (data) { | ||
if (options.schema && data !== null) { | ||
var /** @type {?} */ validation = true; | ||
try { | ||
validation = _this.jsonValidator.validate(data, options.schema); | ||
} | ||
catch (/** @type {?} */ error) { | ||
return _throw(error); | ||
} | ||
if (!validation) { | ||
return _throw(new Error("JSON invalid")); | ||
} | ||
} | ||
return of(data); | ||
})); | ||
}; | ||
/** | ||
* Sets an item in local storage | ||
* @param key The item's key | ||
* @param data The item's value, must NOT be null or undefined | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Sets an item in local storage | ||
* @param {?} key The item's key | ||
* @param {?} data The item's value, must NOT be null or undefined | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
AsyncLocalStorage.prototype.setItem = /** | ||
* Sets an item in local storage | ||
* @param {?} key The item's key | ||
* @param {?} data The item's value, must NOT be null or undefined | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function (key, data) { | ||
return this.database.setItem(key, data); | ||
}; | ||
/** | ||
* Deletes an item in local storage | ||
* @param key The item's key | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Deletes an item in local storage | ||
* @param {?} key The item's key | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
AsyncLocalStorage.prototype.removeItem = /** | ||
* Deletes an item in local storage | ||
* @param {?} key The item's key | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function (key) { | ||
return this.database.removeItem(key); | ||
}; | ||
/** | ||
* Deletes all items from local storage | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Deletes all items from local storage | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
AsyncLocalStorage.prototype.clear = /** | ||
* Deletes all items from local storage | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function () { | ||
return this.database.clear(); | ||
}; | ||
AsyncLocalStorage.decorators = [ | ||
{ type: Injectable }, | ||
]; | ||
/** @nocollapse */ | ||
AsyncLocalStorage.ctorParameters = function () { return [ | ||
{ type: AsyncLocalDatabase, }, | ||
{ type: JSONValidator, }, | ||
]; }; | ||
return AsyncLocalStorage; | ||
}()); | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
*/ | ||
/** | ||
* @param {?} platformId | ||
* @return {?} | ||
*/ | ||
function databaseFactory(platformId) { | ||
function asyncLocalStorageFactory(platformId) { | ||
var /** @type {?} */ database; | ||
if (isPlatformBrowser(platformId) && ('indexedDB' in window) && (indexedDB !== undefined) && (indexedDB !== null)) { | ||
/* Try with IndexedDB in modern browsers */ | ||
return new IndexedDBDatabase(); | ||
database = new IndexedDBDatabase(); | ||
} | ||
else if (isPlatformBrowser(platformId) && ('localStorage' in window) && (localStorage !== undefined) && (localStorage !== null)) { | ||
/* Try with localStorage in old browsers (IE9) */ | ||
return new LocalStorageDatabase(); | ||
database = new LocalStorageDatabase(); | ||
} | ||
else { | ||
/* Fake database for server-side rendering (Universal) */ | ||
return new MockLocalDatabase(); | ||
database = new MockLocalDatabase(); | ||
} | ||
return new AsyncLocalStorage(database); | ||
} | ||
var AsyncLocalStorageModule = (function () { | ||
function AsyncLocalStorageModule() { | ||
} | ||
AsyncLocalStorageModule.decorators = [ | ||
{ type: NgModule, args: [{ | ||
providers: [ | ||
JSONValidator, | ||
{ | ||
provide: AsyncLocalDatabase, | ||
useFactory: databaseFactory, | ||
deps: [PLATFORM_ID] | ||
}, | ||
AsyncLocalStorage, | ||
] | ||
},] }, | ||
]; | ||
/** @nocollapse */ | ||
AsyncLocalStorageModule.ctorParameters = function () { return []; }; | ||
return AsyncLocalStorageModule; | ||
}()); | ||
AsyncLocalStorageModule.decorators = [ | ||
{ type: NgModule, args: [{ | ||
providers: [ | ||
{ | ||
provide: AsyncLocalStorage, | ||
useFactory: asyncLocalStorageFactory, | ||
deps: [PLATFORM_ID] | ||
} | ||
] | ||
},] }, | ||
]; | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
* @nocollapse | ||
*/ | ||
AsyncLocalStorageModule.ctorParameters = function () { return []; }; | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
*/ | ||
/** | ||
* Generated bundle index. Do not edit. | ||
*/ | ||
export { AsyncLocalDatabase, IndexedDBDatabase, LocalStorageDatabase, MockLocalDatabase, JSONValidator, AsyncLocalStorage, AsyncLocalStorageModule, databaseFactory as ɵa }; | ||
export { AsyncLocalStorage, AsyncLocalStorageModule, asyncLocalStorageFactory as ɵa, AsyncLocalDatabase as ɵb }; | ||
//# sourceMappingURL=angular-async-local-storage.es5.js.map |
import { Injectable, NgModule, PLATFORM_ID } from '@angular/core'; | ||
import { isPlatformBrowser } from '@angular/common'; | ||
import { Observable } from 'rxjs/Observable'; | ||
import { ReplaySubject } from 'rxjs/ReplaySubject'; | ||
import { first, map, mergeMap } from 'rxjs/operators'; | ||
import { fromEvent } from 'rxjs/observable/fromEvent'; | ||
import { of } from 'rxjs/observable/of'; | ||
import { _throw } from 'rxjs/observable/throw'; | ||
import { race } from 'rxjs/observable/race'; | ||
import { isPlatformBrowser } from '@angular/common'; | ||
import 'rxjs/add/operator/map'; | ||
import 'rxjs/add/operator/mergeMap'; | ||
import 'rxjs/add/operator/pluck'; | ||
import 'rxjs/add/operator/first'; | ||
import 'rxjs/add/observable/fromEvent'; | ||
import 'rxjs/add/observable/merge'; | ||
import 'rxjs/add/observable/throw'; | ||
import 'rxjs/add/observable/of'; | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
*/ | ||
/** | ||
* @abstract | ||
*/ | ||
class AsyncLocalDatabase { | ||
/** | ||
* @abstract | ||
* @template T | ||
* @param {?} key | ||
* @return {?} | ||
*/ | ||
getItem(key) { } | ||
/** | ||
* @abstract | ||
* @param {?} key | ||
* @param {?} data | ||
* @return {?} | ||
*/ | ||
setItem(key, data) { } | ||
/** | ||
* @abstract | ||
* @param {?} key | ||
* @return {?} | ||
*/ | ||
removeItem(key) { } | ||
/** | ||
* @abstract | ||
* @return {?} | ||
*/ | ||
clear() { } | ||
} | ||
class AsyncLocalStorage { | ||
/** | ||
* Injects a local database | ||
* @param {?} database | ||
*/ | ||
constructor(database) { | ||
this.database = database; | ||
} | ||
/** | ||
* Gets an item value in local storage | ||
* @template T | ||
* @param {?} key The item's key | ||
* @return {?} The item's value if the key exists, null otherwise, wrapped in an RxJS Observable | ||
*/ | ||
getItem(key) { | ||
return this.database.getItem(key); | ||
} | ||
/** | ||
* Sets an item in local storage | ||
* @param {?} key The item's key | ||
* @param {?} data The item's value, must NOT be null or undefined | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
setItem(key, data) { | ||
return this.database.setItem(key, data); | ||
} | ||
/** | ||
* Deletes an item in local storage | ||
* @param {?} key The item's key | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
removeItem(key) { | ||
return this.database.removeItem(key); | ||
} | ||
/** | ||
* Deletes all items from local storage | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
clear() { | ||
return this.database.clear(); | ||
} | ||
} | ||
AsyncLocalStorage.decorators = [ | ||
{ type: Injectable }, | ||
]; | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
* @nocollapse | ||
*/ | ||
AsyncLocalStorage.ctorParameters = () => [ | ||
{ type: AsyncLocalDatabase, }, | ||
]; | ||
class IndexedDBDatabase extends AsyncLocalDatabase { | ||
@@ -59,9 +132,10 @@ /** | ||
/* Opening a trasaction and requesting the item in local storage */ | ||
return this.transaction().pipe(map((transaction) => transaction.get(key)), mergeMap((request) => { | ||
return this.transaction().map((transaction) => transaction.get(key)).mergeMap((request) => { | ||
/* Listening to the success event, and passing the item value if found, null otherwise */ | ||
const /** @type {?} */ success = (/** @type {?} */ (fromEvent(request, 'success'))).pipe(map((event) => (/** @type {?} */ (event.target)).result), map((result) => result && (this.dataPath in result) ? (/** @type {?} */ (result[this.dataPath])) : null)); | ||
let /** @type {?} */ success = Observable.fromEvent(request, 'success') | ||
.pluck('target', 'result') | ||
.map((result) => result ? result[this.dataPath] : null); | ||
/* Merging success and errors events and autoclosing the observable */ | ||
return (/** @type {?} */ (race(success, this.toErrorObservable(request, `getter`)))) | ||
.pipe(first()); | ||
}), first()); | ||
return Observable.merge(success, this.toErrorObservable(request, `getter`)).first(); | ||
}).first(); | ||
} | ||
@@ -77,8 +151,8 @@ /** | ||
if (data == null) { | ||
return of(true); | ||
return Observable.of(true).first(); | ||
} | ||
/* Opening a transaction and checking if the item already exists in local storage */ | ||
return this.getItem(key).pipe(map((existingData) => (existingData == null) ? 'add' : 'put'), mergeMap((method) => { | ||
return this.getItem(key).map((existingData) => (existingData == null) ? 'add' : 'put').mergeMap((method) => { | ||
/* Opening a transaction */ | ||
return this.transaction('readwrite').pipe(mergeMap((transaction) => { | ||
return this.transaction('readwrite').mergeMap((transaction) => { | ||
let /** @type {?} */ request; | ||
@@ -96,6 +170,5 @@ /* Adding or updating local storage, based on previous checking */ | ||
/* Merging success (passing true) and error events and autoclosing the observable */ | ||
return (/** @type {?} */ (race(this.toSuccessObservable(request), this.toErrorObservable(request, `setter`)))) | ||
.pipe(first()); | ||
})); | ||
}), first()); | ||
return Observable.merge(this.toSuccessObservable(request), this.toErrorObservable(request, `setter`)).first(); | ||
}); | ||
}).first(); | ||
} | ||
@@ -109,17 +182,16 @@ /** | ||
/* Opening a transaction and checking if the item exists in local storage */ | ||
return this.getItem(key).pipe(mergeMap((data) => { | ||
return this.getItem(key).mergeMap((data) => { | ||
/* If the item exists in local storage */ | ||
if (data != null) { | ||
/* Opening a transaction */ | ||
return this.transaction('readwrite').pipe(mergeMap((transaction) => { | ||
return this.transaction('readwrite').mergeMap((transaction) => { | ||
/* Deleting the item in local storage */ | ||
const /** @type {?} */ request = transaction.delete(key); | ||
let /** @type {?} */ request = transaction.delete(key); | ||
/* Merging success (passing true) and error events and autoclosing the observable */ | ||
return (/** @type {?} */ (race(this.toSuccessObservable(request), this.toErrorObservable(request, `remover`)))) | ||
.pipe(first()); | ||
})); | ||
return Observable.merge(this.toSuccessObservable(request), this.toErrorObservable(request, `remover`)).first(); | ||
}); | ||
} | ||
/* Passing true if the item does not exist in local storage */ | ||
return of(true); | ||
}), first()); | ||
return Observable.of(true).first(); | ||
}).first(); | ||
} | ||
@@ -132,9 +204,8 @@ /** | ||
/* Opening a transaction */ | ||
return this.transaction('readwrite').pipe(mergeMap((transaction) => { | ||
return this.transaction('readwrite').mergeMap((transaction) => { | ||
/* Deleting all items from local storage */ | ||
const /** @type {?} */ request = transaction.clear(); | ||
let /** @type {?} */ request = transaction.clear(); | ||
/* Merging success (passing true) and error events and autoclosing the observable */ | ||
return (/** @type {?} */ (race(this.toSuccessObservable(request), this.toErrorObservable(request, `clearer`)))) | ||
.pipe(first()); | ||
}), first()); | ||
return Observable.merge(this.toSuccessObservable(request), this.toErrorObservable(request, `clearer`)).first(); | ||
}).first(); | ||
} | ||
@@ -147,9 +218,7 @@ /** | ||
/* Connecting to IndexedDB */ | ||
const /** @type {?} */ request = indexedDB.open(this.dbName); | ||
let /** @type {?} */ request = indexedDB.open(this.dbName); | ||
/* Listening the event fired on first connection, creating the object store for local storage */ | ||
(/** @type {?} */ (fromEvent(request, 'upgradeneeded'))) | ||
.pipe(first()) | ||
.subscribe((event) => { | ||
Observable.fromEvent(request, 'upgradeneeded').first().subscribe((event) => { | ||
/* Getting the database connection */ | ||
const /** @type {?} */ database = /** @type {?} */ ((/** @type {?} */ (event.target)).result); | ||
let /** @type {?} */ database = (((event.target)).result); | ||
/* Checking if the object store already exists, to avoid error */ | ||
@@ -162,9 +231,7 @@ if (!database.objectStoreNames.contains(this.objectStoreName)) { | ||
/* Listening the success event and converting to an RxJS Observable */ | ||
const /** @type {?} */ success = /** @type {?} */ (fromEvent(request, 'success')); | ||
let /** @type {?} */ success = Observable.fromEvent(request, 'success'); | ||
/* Merging success and errors events */ | ||
(/** @type {?} */ (race(success, this.toErrorObservable(request, `connection`)))) | ||
.pipe(first()) | ||
.subscribe((event) => { | ||
Observable.merge(success, this.toErrorObservable(request, `connection`)).first().subscribe((event) => { | ||
/* Storing the database connection for further access */ | ||
this.database.next(/** @type {?} */ ((/** @type {?} */ (event.target)).result)); | ||
this.database.next(/** @type {?} */ (((event.target)).result)); | ||
}, (error) => { | ||
@@ -181,4 +248,3 @@ this.database.error(/** @type {?} */ (error)); | ||
/* From the IndexedDB connection, opening a transaction and getting the local storage objet store */ | ||
return this.database | ||
.pipe(map((database) => database.transaction([this.objectStoreName], mode).objectStore(this.objectStoreName))); | ||
return this.database.map((database) => database.transaction([this.objectStoreName], mode).objectStore(this.objectStoreName)); | ||
} | ||
@@ -192,4 +258,3 @@ /** | ||
/* Transforming a IndexedDB success event in an RxJS Observable with true value */ | ||
return (/** @type {?} */ (fromEvent(request, 'success'))) | ||
.pipe(map(() => true)); | ||
return Observable.fromEvent(request, 'success').map(() => true); | ||
} | ||
@@ -204,4 +269,3 @@ /** | ||
/* Transforming a IndexedDB error event in an RxJS ErrorObservable */ | ||
return (/** @type {?} */ (fromEvent(request, 'error'))) | ||
.pipe(mergeMap((event) => _throw(new Error(`IndexedDB ${error} issue : ${request.error.message}.`)))); | ||
return Observable.fromEvent(request, 'error').mergeMap(() => Observable.throw(new Error(`IndexedDB ${error} issue.`))); | ||
} | ||
@@ -212,9 +276,7 @@ } | ||
]; | ||
/** @nocollapse */ | ||
/** | ||
* @nocollapse | ||
*/ | ||
IndexedDBDatabase.ctorParameters = () => []; | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
*/ | ||
class LocalStorageDatabase extends AsyncLocalDatabase { | ||
@@ -233,13 +295,12 @@ constructor() { | ||
getItem(key) { | ||
const /** @type {?} */ unparsedData = this.localStorage.getItem(key); | ||
let /** @type {?} */ parsedData = null; | ||
if (unparsedData != null) { | ||
let /** @type {?} */ data = this.localStorage.getItem(key); | ||
if (data != null) { | ||
try { | ||
parsedData = JSON.parse(unparsedData); | ||
data = JSON.parse(data); | ||
} | ||
catch (/** @type {?} */ error) { | ||
return _throw(new Error(`Invalid data in localStorage.`)); | ||
catch (error) { | ||
return Observable.throw(new Error(`Invalid data in localStorage.`)); | ||
} | ||
} | ||
return of(parsedData); | ||
return Observable.of(data); | ||
} | ||
@@ -254,3 +315,3 @@ /** | ||
this.localStorage.setItem(key, JSON.stringify(data)); | ||
return of(true); | ||
return Observable.of(true); | ||
} | ||
@@ -264,3 +325,3 @@ /** | ||
this.localStorage.removeItem(key); | ||
return of(true); | ||
return Observable.of(true); | ||
} | ||
@@ -273,3 +334,3 @@ /** | ||
this.localStorage.clear(); | ||
return of(true); | ||
return Observable.of(true); | ||
} | ||
@@ -280,9 +341,7 @@ } | ||
]; | ||
/** @nocollapse */ | ||
/** | ||
* @nocollapse | ||
*/ | ||
LocalStorageDatabase.ctorParameters = () => []; | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
*/ | ||
class MockLocalDatabase extends AsyncLocalDatabase { | ||
@@ -300,4 +359,4 @@ constructor() { | ||
getItem(key) { | ||
const /** @type {?} */ rawData = this.localStorage.get(key); | ||
return of((rawData !== undefined) ? rawData : null); | ||
let /** @type {?} */ data = this.localStorage.get(key); | ||
return Observable.of((data !== undefined) ? data : null); | ||
} | ||
@@ -312,3 +371,3 @@ /** | ||
this.localStorage.set(key, data); | ||
return of(true); | ||
return Observable.of(true); | ||
} | ||
@@ -322,3 +381,3 @@ /** | ||
this.localStorage.delete(key); | ||
return of(true); | ||
return Observable.of(true); | ||
} | ||
@@ -331,3 +390,3 @@ /** | ||
this.localStorage.clear(); | ||
return of(true); | ||
return Observable.of(true); | ||
} | ||
@@ -338,287 +397,28 @@ } | ||
]; | ||
/** @nocollapse */ | ||
MockLocalDatabase.ctorParameters = () => []; | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
* @nocollapse | ||
*/ | ||
/** | ||
* \@todo Add other JSON Schema validation features | ||
*/ | ||
class JSONValidator { | ||
constructor() { | ||
this.simpleTypes = ['string', 'number', 'boolean', 'object']; | ||
} | ||
/** | ||
* @param {?} value | ||
* @return {?} | ||
*/ | ||
isObjectNotNull(value) { | ||
return (value !== null) && (typeof value === 'object'); | ||
} | ||
/** | ||
* Validate a JSON data against a JSON Schema | ||
* @param {?} data JSON data to validate | ||
* @param {?} schema Subset of JSON Schema | ||
* @return {?} If data is valid : true, if it is invalid : false, and throws if the schema is invalid | ||
*/ | ||
validate(data, schema) { | ||
if (!this.isObjectNotNull(schema)) { | ||
throw new Error(`A schema must be an object (unlike spec, booleans are not supported to enforce strict types).`); | ||
} | ||
if ((!schema.hasOwnProperty('type') || schema.type === 'array' || schema.type === 'object') | ||
&& !schema.hasOwnProperty('properties') && !schema.hasOwnProperty('items')) { | ||
throw new Error(`Each value must have a 'type' or 'properties' or 'items', to enforce strict types.`); | ||
} | ||
if (schema.hasOwnProperty('type') && !this.validateType(data, schema)) { | ||
return false; | ||
} | ||
if (schema.hasOwnProperty('items') && !this.validateItems(data, schema)) { | ||
return false; | ||
} | ||
if (schema.hasOwnProperty('properties')) { | ||
if (schema.hasOwnProperty('required') && !this.validateRequired(data, schema)) { | ||
return false; | ||
} | ||
if (!this.validateProperties(data, schema)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
/** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
validateProperties(data, schema) { | ||
if (!this.isObjectNotNull(data)) { | ||
return false; | ||
} | ||
if (!schema.properties || !this.isObjectNotNull(schema.properties)) { | ||
throw new Error(`'properties' must be a schema object.`); | ||
} | ||
/** | ||
* Check if the object doesn't have more properties than expected | ||
* Equivalent of additionalProperties: false | ||
*/ | ||
if (Object.keys(schema.properties).length !== Object.keys(data).length) { | ||
return false; | ||
} | ||
/* Recursively validate all properties */ | ||
for (let /** @type {?} */ property in schema.properties) { | ||
if (schema.properties.hasOwnProperty(property) && data.hasOwnProperty(property)) { | ||
if (!this.validate(data[property], schema.properties[property])) { | ||
return false; | ||
} | ||
} | ||
} | ||
return true; | ||
} | ||
/** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
validateRequired(data, schema) { | ||
if (!this.isObjectNotNull(data)) { | ||
return false; | ||
} | ||
if (!Array.isArray(schema.required)) { | ||
throw new Error(`'required' field must be an array. Note that since JSON Schema draft 6, booleans are not supported anymore.`); | ||
} | ||
for (let /** @type {?} */ requiredProp of schema.required) { | ||
if (typeof requiredProp !== 'string') { | ||
throw new Error(`'required' array must contain strings only.`); | ||
} | ||
/* Checks if the property is present in the schema 'properties' */ | ||
if (!schema.properties || !schema.properties.hasOwnProperty(requiredProp)) { | ||
throw new Error(`'required' properties must be described in 'properties' too.`); | ||
} | ||
/* Checks if the property is present in the data */ | ||
if (!data.hasOwnProperty(requiredProp)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
/** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
validateType(data, schema) { | ||
if (Array.isArray(schema.type)) { | ||
return this.validateTypeList(data, schema); | ||
} | ||
if (typeof schema.type !== 'string') { | ||
throw new Error(`'type' must be a string (arrays of types are not supported yet).`); | ||
} | ||
if ((schema.type === 'null') && (data !== null)) { | ||
return false; | ||
} | ||
if ((this.simpleTypes.indexOf(schema.type) !== -1) && (typeof data !== schema.type)) { | ||
return false; | ||
} | ||
if ((schema.type === 'integer') && ((typeof data !== 'number') || !Number.isInteger(data))) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
/** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
validateTypeList(data, schema) { | ||
const /** @type {?} */ types = /** @type {?} */ (schema.type); | ||
const /** @type {?} */ typesTests = []; | ||
for (let /** @type {?} */ type of types) { | ||
typesTests.push(this.validateType(data, { type })); | ||
} | ||
return (typesTests.indexOf(true) !== -1); | ||
} | ||
/** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
validateItems(data, schema) { | ||
if (!Array.isArray(data)) { | ||
return false; | ||
} | ||
if (Array.isArray(schema.items)) { | ||
return this.validateItemsList(data, schema); | ||
} | ||
if (!schema.items || !this.isObjectNotNull(schema.items)) { | ||
throw new Error(`'items' must be a schema object.`); | ||
} | ||
for (let /** @type {?} */ value of data) { | ||
if (!this.validate(value, schema.items)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
/** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
validateItemsList(data, schema) { | ||
const /** @type {?} */ items = /** @type {?} */ (schema.items); | ||
if (data.length !== items.length) { | ||
return false; | ||
} | ||
for (let /** @type {?} */ i = 0; i < items.length; i += 1) { | ||
if (!this.validate(data[i], items[i])) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
} | ||
MockLocalDatabase.ctorParameters = () => []; | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
*/ | ||
/** | ||
* @record | ||
*/ | ||
class AsyncLocalStorage { | ||
/** | ||
* @param {?} database | ||
* @param {?} jsonValidator | ||
*/ | ||
constructor(database, jsonValidator) { | ||
this.database = database; | ||
this.jsonValidator = jsonValidator; | ||
this.getItemOptionsDefault = { | ||
schema: null | ||
}; | ||
} | ||
/** | ||
* Gets an item value in local storage | ||
* @template T | ||
* @param {?} key The item's key | ||
* @param {?=} options | ||
* @return {?} The item's value if the key exists, null otherwise, wrapped in an RxJS Observable | ||
*/ | ||
getItem(key, options = this.getItemOptionsDefault) { | ||
return this.database.getItem(key).pipe(/* Validate data upon a json schema if requested */ | ||
mergeMap((data) => { | ||
if (options.schema && data !== null) { | ||
let /** @type {?} */ validation = true; | ||
try { | ||
validation = this.jsonValidator.validate(data, options.schema); | ||
} | ||
catch (/** @type {?} */ error) { | ||
return _throw(error); | ||
} | ||
if (!validation) { | ||
return _throw(new Error(`JSON invalid`)); | ||
} | ||
} | ||
return of(data); | ||
})); | ||
} | ||
/** | ||
* Sets an item in local storage | ||
* @param {?} key The item's key | ||
* @param {?} data The item's value, must NOT be null or undefined | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
setItem(key, data) { | ||
return this.database.setItem(key, data); | ||
} | ||
/** | ||
* Deletes an item in local storage | ||
* @param {?} key The item's key | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
removeItem(key) { | ||
return this.database.removeItem(key); | ||
} | ||
/** | ||
* Deletes all items from local storage | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
clear() { | ||
return this.database.clear(); | ||
} | ||
} | ||
AsyncLocalStorage.decorators = [ | ||
{ type: Injectable }, | ||
]; | ||
/** @nocollapse */ | ||
AsyncLocalStorage.ctorParameters = () => [ | ||
{ type: AsyncLocalDatabase, }, | ||
{ type: JSONValidator, }, | ||
]; | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
*/ | ||
/** | ||
* @param {?} platformId | ||
* @return {?} | ||
*/ | ||
function databaseFactory(platformId) { | ||
function asyncLocalStorageFactory(platformId) { | ||
let /** @type {?} */ database; | ||
if (isPlatformBrowser(platformId) && ('indexedDB' in window) && (indexedDB !== undefined) && (indexedDB !== null)) { | ||
/* Try with IndexedDB in modern browsers */ | ||
return new IndexedDBDatabase(); | ||
database = new IndexedDBDatabase(); | ||
} | ||
else if (isPlatformBrowser(platformId) && ('localStorage' in window) && (localStorage !== undefined) && (localStorage !== null)) { | ||
/* Try with localStorage in old browsers (IE9) */ | ||
return new LocalStorageDatabase(); | ||
database = new LocalStorageDatabase(); | ||
} | ||
else { | ||
/* Fake database for server-side rendering (Universal) */ | ||
return new MockLocalDatabase(); | ||
database = new MockLocalDatabase(); | ||
} | ||
return new AsyncLocalStorage(database); | ||
} | ||
class AsyncLocalStorageModule { | ||
@@ -629,29 +429,20 @@ } | ||
providers: [ | ||
JSONValidator, | ||
{ | ||
provide: AsyncLocalDatabase, | ||
useFactory: databaseFactory, | ||
provide: AsyncLocalStorage, | ||
useFactory: asyncLocalStorageFactory, | ||
deps: [PLATFORM_ID] | ||
}, | ||
AsyncLocalStorage, | ||
} | ||
] | ||
},] }, | ||
]; | ||
/** @nocollapse */ | ||
AsyncLocalStorageModule.ctorParameters = () => []; | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
* @nocollapse | ||
*/ | ||
AsyncLocalStorageModule.ctorParameters = () => []; | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
*/ | ||
/** | ||
* Generated bundle index. Do not edit. | ||
*/ | ||
export { AsyncLocalDatabase, IndexedDBDatabase, LocalStorageDatabase, MockLocalDatabase, JSONValidator, AsyncLocalStorage, AsyncLocalStorageModule, databaseFactory as ɵa }; | ||
export { AsyncLocalStorage, AsyncLocalStorageModule, asyncLocalStorageFactory as ɵa, AsyncLocalDatabase as ɵb }; | ||
//# sourceMappingURL=angular-async-local-storage.js.map |
@@ -1,1 +0,1 @@ | ||
{"__symbolic":"module","version":4,"metadata":{"JSONSchema":{"__symbolic":"interface"},"JSONSchemaType":{"__symbolic":"interface"},"AsyncLocalDatabase":{"__symbolic":"class","members":{"getItem":[{"__symbolic":"method"}],"setItem":[{"__symbolic":"method"}],"removeItem":[{"__symbolic":"method"}],"clear":[{"__symbolic":"method"}]}},"IndexedDBDatabase":{"__symbolic":"class","extends":{"__symbolic":"reference","name":"AsyncLocalDatabase"},"decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Injectable","line":12,"character":1}}],"members":{"__ctor__":[{"__symbolic":"constructor"}],"getItem":[{"__symbolic":"method"}],"setItem":[{"__symbolic":"method"}],"removeItem":[{"__symbolic":"method"}],"clear":[{"__symbolic":"method"}],"connect":[{"__symbolic":"method"}],"transaction":[{"__symbolic":"method"}],"toSuccessObservable":[{"__symbolic":"method"}],"toErrorObservable":[{"__symbolic":"method"}]}},"LocalStorageDatabase":{"__symbolic":"class","extends":{"__symbolic":"reference","name":"AsyncLocalDatabase"},"decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Injectable","line":8,"character":1}}],"members":{"getItem":[{"__symbolic":"method"}],"setItem":[{"__symbolic":"method"}],"removeItem":[{"__symbolic":"method"}],"clear":[{"__symbolic":"method"}]}},"MockLocalDatabase":{"__symbolic":"class","extends":{"__symbolic":"reference","name":"AsyncLocalDatabase"},"decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Injectable","line":7,"character":1}}],"members":{"getItem":[{"__symbolic":"method"}],"setItem":[{"__symbolic":"method"}],"removeItem":[{"__symbolic":"method"}],"clear":[{"__symbolic":"method"}]}},"JSONValidator":{"__symbolic":"class","members":{"isObjectNotNull":[{"__symbolic":"method"}],"validate":[{"__symbolic":"method"}],"validateProperties":[{"__symbolic":"method"}],"validateRequired":[{"__symbolic":"method"}],"validateType":[{"__symbolic":"method"}],"validateTypeList":[{"__symbolic":"method"}],"validateItems":[{"__symbolic":"method"}],"validateItemsList":[{"__symbolic":"method"}]}},"ALSGetItemOptions":{"__symbolic":"interface"},"AsyncLocalStorage":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Injectable","line":14,"character":1}}],"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","name":"AsyncLocalDatabase"},{"__symbolic":"reference","name":"JSONValidator"}]}],"getItem":[{"__symbolic":"method"}],"setItem":[{"__symbolic":"method"}],"removeItem":[{"__symbolic":"method"}],"clear":[{"__symbolic":"method"}]}},"ɵa":{"__symbolic":"function"},"AsyncLocalStorageModule":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"NgModule","line":31,"character":1},"arguments":[{"providers":[{"__symbolic":"reference","name":"JSONValidator"},{"provide":{"__symbolic":"reference","name":"AsyncLocalDatabase"},"useFactory":{"__symbolic":"reference","name":"ɵa"},"deps":[{"__symbolic":"reference","module":"@angular/core","name":"PLATFORM_ID","line":37,"character":13}]},{"__symbolic":"reference","name":"AsyncLocalStorage"}]}]}],"members":{}}},"origins":{"JSONSchema":"./src/service/validation/json-schema","JSONSchemaType":"./src/service/validation/json-schema","AsyncLocalDatabase":"./src/service/databases/async-local-database","IndexedDBDatabase":"./src/service/databases/indexeddb-database","LocalStorageDatabase":"./src/service/databases/localstorage-database","MockLocalDatabase":"./src/service/databases/mock-local-database","JSONValidator":"./src/service/validation/json-validator","ALSGetItemOptions":"./src/service/lib.service","AsyncLocalStorage":"./src/service/lib.service","ɵa":"./src/module","AsyncLocalStorageModule":"./src/module"},"importAs":"angular-async-local-storage"} | ||
{"__symbolic":"module","version":3,"metadata":{"AsyncLocalStorage":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Injectable"}}],"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","name":"ɵb"}]}],"getItem":[{"__symbolic":"method"}],"setItem":[{"__symbolic":"method"}],"removeItem":[{"__symbolic":"method"}],"clear":[{"__symbolic":"method"}]}},"ɵa":{"__symbolic":"function"},"AsyncLocalStorageModule":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"NgModule"},"arguments":[{"providers":[{"provide":{"__symbolic":"reference","name":"AsyncLocalStorage"},"useFactory":{"__symbolic":"reference","name":"ɵa"},"deps":[{"__symbolic":"reference","module":"@angular/core","name":"PLATFORM_ID"}]}]}]}],"members":{}},"ɵb":{"__symbolic":"class","members":{"getItem":[{"__symbolic":"method"}],"setItem":[{"__symbolic":"method"}],"removeItem":[{"__symbolic":"method"}],"clear":[{"__symbolic":"method"}]}}},"origins":{"AsyncLocalStorage":"./src/service/lib.service","ɵa":"./src/module","AsyncLocalStorageModule":"./src/module","ɵb":"./src/service/databases/async-local-database"},"importAs":"angular-async-local-storage"} |
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('rxjs/ReplaySubject'), require('rxjs/operators'), require('rxjs/observable/fromEvent'), require('rxjs/observable/of'), require('rxjs/observable/throw'), require('rxjs/observable/race'), require('@angular/common')) : | ||
typeof define === 'function' && define.amd ? define(['exports', '@angular/core', 'rxjs/ReplaySubject', 'rxjs/operators', 'rxjs/observable/fromEvent', 'rxjs/observable/of', 'rxjs/observable/throw', 'rxjs/observable/race', '@angular/common'], factory) : | ||
(factory((global.angularAsyncLocalStorage = global.angularAsyncLocalStorage || {}),global.ng.core,global.Rx,global.Rx.operators,global.Rx.Observable,global.Rx.Observable,global.Rx.Observable,global.Rx.Observable,global.ng.common)); | ||
}(this, (function (exports,_angular_core,rxjs_ReplaySubject,rxjs_operators,rxjs_observable_fromEvent,rxjs_observable_of,rxjs_observable_throw,rxjs_observable_race,_angular_common) { 'use strict'; | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/common'), require('rxjs/Observable'), require('rxjs/ReplaySubject'), require('rxjs/add/operator/map'), require('rxjs/add/operator/mergeMap'), require('rxjs/add/operator/pluck'), require('rxjs/add/operator/first'), require('rxjs/add/observable/fromEvent'), require('rxjs/add/observable/merge'), require('rxjs/add/observable/throw'), require('rxjs/add/observable/of')) : | ||
typeof define === 'function' && define.amd ? define(['exports', '@angular/core', '@angular/common', 'rxjs/Observable', 'rxjs/ReplaySubject', 'rxjs/add/operator/map', 'rxjs/add/operator/mergeMap', 'rxjs/add/operator/pluck', 'rxjs/add/operator/first', 'rxjs/add/observable/fromEvent', 'rxjs/add/observable/merge', 'rxjs/add/observable/throw', 'rxjs/add/observable/of'], factory) : | ||
(factory((global.angularAsyncLocalStorage = global.angularAsyncLocalStorage || {}),global.ng.core,global.ng.common,global.Rx,global.Rx)); | ||
}(this, (function (exports,_angular_core,_angular_common,rxjs_Observable,rxjs_ReplaySubject) { 'use strict'; | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
*/ | ||
/** | ||
* @abstract | ||
@@ -17,5 +13,83 @@ */ | ||
} | ||
/** | ||
* @abstract | ||
* @template T | ||
* @param {?} key | ||
* @return {?} | ||
*/ | ||
AsyncLocalDatabase.prototype.getItem = function (key) { }; | ||
/** | ||
* @abstract | ||
* @param {?} key | ||
* @param {?} data | ||
* @return {?} | ||
*/ | ||
AsyncLocalDatabase.prototype.setItem = function (key, data) { }; | ||
/** | ||
* @abstract | ||
* @param {?} key | ||
* @return {?} | ||
*/ | ||
AsyncLocalDatabase.prototype.removeItem = function (key) { }; | ||
/** | ||
* @abstract | ||
* @return {?} | ||
*/ | ||
AsyncLocalDatabase.prototype.clear = function () { }; | ||
return AsyncLocalDatabase; | ||
}()); | ||
var AsyncLocalStorage = (function () { | ||
/** | ||
* Injects a local database | ||
* @param {?} database | ||
*/ | ||
function AsyncLocalStorage(database) { | ||
this.database = database; | ||
} | ||
/** | ||
* Gets an item value in local storage | ||
* @template T | ||
* @param {?} key The item's key | ||
* @return {?} The item's value if the key exists, null otherwise, wrapped in an RxJS Observable | ||
*/ | ||
AsyncLocalStorage.prototype.getItem = function (key) { | ||
return this.database.getItem(key); | ||
}; | ||
/** | ||
* Sets an item in local storage | ||
* @param {?} key The item's key | ||
* @param {?} data The item's value, must NOT be null or undefined | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
AsyncLocalStorage.prototype.setItem = function (key, data) { | ||
return this.database.setItem(key, data); | ||
}; | ||
/** | ||
* Deletes an item in local storage | ||
* @param {?} key The item's key | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
AsyncLocalStorage.prototype.removeItem = function (key) { | ||
return this.database.removeItem(key); | ||
}; | ||
/** | ||
* Deletes all items from local storage | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
AsyncLocalStorage.prototype.clear = function () { | ||
return this.database.clear(); | ||
}; | ||
return AsyncLocalStorage; | ||
}()); | ||
AsyncLocalStorage.decorators = [ | ||
{ type: _angular_core.Injectable }, | ||
]; | ||
/** | ||
* @nocollapse | ||
*/ | ||
AsyncLocalStorage.ctorParameters = function () { return [ | ||
{ type: AsyncLocalDatabase, }, | ||
]; }; | ||
var __extends = (undefined && undefined.__extends) || (function () { | ||
@@ -31,6 +105,2 @@ var extendStatics = Object.setPrototypeOf || | ||
})(); | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
*/ | ||
var IndexedDBDatabase = (function (_super) { | ||
@@ -60,6 +130,4 @@ __extends(IndexedDBDatabase, _super); | ||
/* Creating the RxJS ReplaySubject */ | ||
/* Creating the RxJS ReplaySubject */ | ||
_this.database = new rxjs_ReplaySubject.ReplaySubject(); | ||
/* Connecting to IndexedDB */ | ||
/* Connecting to IndexedDB */ | ||
_this.connect(); | ||
@@ -70,7 +138,2 @@ return _this; | ||
* Gets an item value in local storage | ||
* @param key The item's key | ||
* @returns The item's value if the key exists, null otherwise, wrapped in an RxJS Observable | ||
*/ | ||
/** | ||
* Gets an item value in local storage | ||
* @template T | ||
@@ -80,27 +143,16 @@ * @param {?} key The item's key | ||
*/ | ||
IndexedDBDatabase.prototype.getItem = /** | ||
* Gets an item value in local storage | ||
* @template T | ||
* @param {?} key The item's key | ||
* @return {?} The item's value if the key exists, null otherwise, wrapped in an RxJS Observable | ||
*/ | ||
function (key) { | ||
IndexedDBDatabase.prototype.getItem = function (key) { | ||
var _this = this; | ||
/* Opening a trasaction and requesting the item in local storage */ | ||
return this.transaction().pipe(rxjs_operators.map(function (transaction) { return transaction.get(key); }), rxjs_operators.mergeMap(function (request) { | ||
return this.transaction().map(function (transaction) { return transaction.get(key); }).mergeMap(function (request) { | ||
/* Listening to the success event, and passing the item value if found, null otherwise */ | ||
var /** @type {?} */ success = (/** @type {?} */ (rxjs_observable_fromEvent.fromEvent(request, 'success'))).pipe(rxjs_operators.map(function (event) { return (/** @type {?} */ (event.target)).result; }), rxjs_operators.map(function (result) { return result && (_this.dataPath in result) ? (/** @type {?} */ (result[_this.dataPath])) : null; })); | ||
var /** @type {?} */ success = rxjs_Observable.Observable.fromEvent(request, 'success') | ||
.pluck('target', 'result') | ||
.map(function (result) { return result ? result[_this.dataPath] : null; }); | ||
/* Merging success and errors events and autoclosing the observable */ | ||
return (/** @type {?} */ (rxjs_observable_race.race(success, _this.toErrorObservable(request, "getter")))) | ||
.pipe(rxjs_operators.first()); | ||
}), rxjs_operators.first()); | ||
return rxjs_Observable.Observable.merge(success, _this.toErrorObservable(request, "getter")).first(); | ||
}).first(); | ||
}; | ||
/** | ||
* Sets an item in local storage | ||
* @param key The item's key | ||
* @param data The item's value, must NOT be null or undefined | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Sets an item in local storage | ||
* @param {?} key The item's key | ||
@@ -110,18 +162,12 @@ * @param {?} data The item's value, must NOT be null or undefined | ||
*/ | ||
IndexedDBDatabase.prototype.setItem = /** | ||
* Sets an item in local storage | ||
* @param {?} key The item's key | ||
* @param {?} data The item's value, must NOT be null or undefined | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function (key, data) { | ||
IndexedDBDatabase.prototype.setItem = function (key, data) { | ||
var _this = this; | ||
/* Storing null is not correctly supported by IndexedDB and unnecessary here */ | ||
if (data == null) { | ||
return rxjs_observable_of.of(true); | ||
return rxjs_Observable.Observable.of(true).first(); | ||
} | ||
/* Opening a transaction and checking if the item already exists in local storage */ | ||
return this.getItem(key).pipe(rxjs_operators.map(function (existingData) { return (existingData == null) ? 'add' : 'put'; }), rxjs_operators.mergeMap(function (method) { | ||
return this.getItem(key).map(function (existingData) { return (existingData == null) ? 'add' : 'put'; }).mergeMap(function (method) { | ||
/* Opening a transaction */ | ||
return _this.transaction('readwrite').pipe(rxjs_operators.mergeMap(function (transaction) { | ||
return _this.transaction('readwrite').mergeMap(function (transaction) { | ||
var /** @type {?} */ request; | ||
@@ -139,77 +185,49 @@ /* Adding or updating local storage, based on previous checking */ | ||
/* Merging success (passing true) and error events and autoclosing the observable */ | ||
return (/** @type {?} */ (rxjs_observable_race.race(_this.toSuccessObservable(request), _this.toErrorObservable(request, "setter")))) | ||
.pipe(rxjs_operators.first()); | ||
return rxjs_Observable.Observable.merge(_this.toSuccessObservable(request), _this.toErrorObservable(request, "setter")).first(); | ||
var _a, _b; | ||
})); | ||
}), rxjs_operators.first()); | ||
}); | ||
}).first(); | ||
}; | ||
/** | ||
* Deletes an item in local storage | ||
* @param key The item's key | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Deletes an item in local storage | ||
* @param {?} key The item's key | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
IndexedDBDatabase.prototype.removeItem = /** | ||
* Deletes an item in local storage | ||
* @param {?} key The item's key | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function (key) { | ||
IndexedDBDatabase.prototype.removeItem = function (key) { | ||
var _this = this; | ||
/* Opening a transaction and checking if the item exists in local storage */ | ||
return this.getItem(key).pipe(rxjs_operators.mergeMap(function (data) { | ||
return this.getItem(key).mergeMap(function (data) { | ||
/* If the item exists in local storage */ | ||
if (data != null) { | ||
/* Opening a transaction */ | ||
return _this.transaction('readwrite').pipe(rxjs_operators.mergeMap(function (transaction) { | ||
return _this.transaction('readwrite').mergeMap(function (transaction) { | ||
/* Deleting the item in local storage */ | ||
var /** @type {?} */ request = transaction.delete(key); | ||
/* Merging success (passing true) and error events and autoclosing the observable */ | ||
return (/** @type {?} */ (rxjs_observable_race.race(_this.toSuccessObservable(request), _this.toErrorObservable(request, "remover")))) | ||
.pipe(rxjs_operators.first()); | ||
})); | ||
return rxjs_Observable.Observable.merge(_this.toSuccessObservable(request), _this.toErrorObservable(request, "remover")).first(); | ||
}); | ||
} | ||
/* Passing true if the item does not exist in local storage */ | ||
return rxjs_observable_of.of(true); | ||
}), rxjs_operators.first()); | ||
return rxjs_Observable.Observable.of(true).first(); | ||
}).first(); | ||
}; | ||
/** | ||
* Deletes all items from local storage | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Deletes all items from local storage | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
IndexedDBDatabase.prototype.clear = /** | ||
* Deletes all items from local storage | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function () { | ||
IndexedDBDatabase.prototype.clear = function () { | ||
var _this = this; | ||
/* Opening a transaction */ | ||
return this.transaction('readwrite').pipe(rxjs_operators.mergeMap(function (transaction) { | ||
return this.transaction('readwrite').mergeMap(function (transaction) { | ||
/* Deleting all items from local storage */ | ||
var /** @type {?} */ request = transaction.clear(); | ||
/* Merging success (passing true) and error events and autoclosing the observable */ | ||
return (/** @type {?} */ (rxjs_observable_race.race(_this.toSuccessObservable(request), _this.toErrorObservable(request, "clearer")))) | ||
.pipe(rxjs_operators.first()); | ||
}), rxjs_operators.first()); | ||
return rxjs_Observable.Observable.merge(_this.toSuccessObservable(request), _this.toErrorObservable(request, "clearer")).first(); | ||
}).first(); | ||
}; | ||
/** | ||
* Connects to IndexedDB and creates the object store on first time | ||
*/ | ||
/** | ||
* Connects to IndexedDB and creates the object store on first time | ||
* @return {?} | ||
*/ | ||
IndexedDBDatabase.prototype.connect = /** | ||
* Connects to IndexedDB and creates the object store on first time | ||
* @return {?} | ||
*/ | ||
function () { | ||
IndexedDBDatabase.prototype.connect = function () { | ||
var _this = this; | ||
@@ -219,7 +237,5 @@ /* Connecting to IndexedDB */ | ||
/* Listening the event fired on first connection, creating the object store for local storage */ | ||
(/** @type {?} */ (rxjs_observable_fromEvent.fromEvent(request, 'upgradeneeded'))) | ||
.pipe(rxjs_operators.first()) | ||
.subscribe(function (event) { | ||
rxjs_Observable.Observable.fromEvent(request, 'upgradeneeded').first().subscribe(function (event) { | ||
/* Getting the database connection */ | ||
var /** @type {?} */ database = /** @type {?} */ ((/** @type {?} */ (event.target)).result); | ||
var /** @type {?} */ database = (((event.target)).result); | ||
/* Checking if the object store already exists, to avoid error */ | ||
@@ -232,10 +248,7 @@ if (!database.objectStoreNames.contains(_this.objectStoreName)) { | ||
/* Listening the success event and converting to an RxJS Observable */ | ||
var /** @type {?} */ success = /** @type {?} */ (rxjs_observable_fromEvent.fromEvent(request, 'success')); | ||
var /** @type {?} */ success = rxjs_Observable.Observable.fromEvent(request, 'success'); | ||
/* Merging success and errors events */ | ||
(/** @type {?} */ (rxjs_observable_race.race(success, this.toErrorObservable(request, "connection")))) | ||
.pipe(rxjs_operators.first()) | ||
.subscribe(function (event) { | ||
rxjs_Observable.Observable.merge(success, this.toErrorObservable(request, "connection")).first().subscribe(function (event) { | ||
/* Storing the database connection for further access */ | ||
/* Storing the database connection for further access */ | ||
_this.database.next(/** @type {?} */ ((/** @type {?} */ (event.target)).result)); | ||
_this.database.next(/** @type {?} */ (((event.target)).result)); | ||
}, function (error) { | ||
@@ -247,50 +260,22 @@ _this.database.error(/** @type {?} */ (error)); | ||
* Opens an IndexedDB transaction and gets the local storage object store | ||
* @param mode Default to 'readonly' for read operations, or 'readwrite' for write operations | ||
* @returns An IndexedDB transaction object store, wrapped in an RxJS Observable | ||
*/ | ||
/** | ||
* Opens an IndexedDB transaction and gets the local storage object store | ||
* @param {?=} mode Default to 'readonly' for read operations, or 'readwrite' for write operations | ||
* @return {?} An IndexedDB transaction object store, wrapped in an RxJS Observable | ||
*/ | ||
IndexedDBDatabase.prototype.transaction = /** | ||
* Opens an IndexedDB transaction and gets the local storage object store | ||
* @param {?=} mode Default to 'readonly' for read operations, or 'readwrite' for write operations | ||
* @return {?} An IndexedDB transaction object store, wrapped in an RxJS Observable | ||
*/ | ||
function (mode) { | ||
IndexedDBDatabase.prototype.transaction = function (mode) { | ||
var _this = this; | ||
if (mode === void 0) { mode = 'readonly'; } | ||
/* From the IndexedDB connection, opening a transaction and getting the local storage objet store */ | ||
return this.database | ||
.pipe(rxjs_operators.map(function (database) { return database.transaction([_this.objectStoreName], mode).objectStore(_this.objectStoreName); })); | ||
return this.database.map(function (database) { return database.transaction([_this.objectStoreName], mode).objectStore(_this.objectStoreName); }); | ||
}; | ||
/** | ||
* Transforms a IndexedDB success event in an RxJS Observable | ||
* @param request The request to listen | ||
* @returns A RxJS Observable with true value | ||
*/ | ||
/** | ||
* Transforms a IndexedDB success event in an RxJS Observable | ||
* @param {?} request The request to listen | ||
* @return {?} A RxJS Observable with true value | ||
*/ | ||
IndexedDBDatabase.prototype.toSuccessObservable = /** | ||
* Transforms a IndexedDB success event in an RxJS Observable | ||
* @param {?} request The request to listen | ||
* @return {?} A RxJS Observable with true value | ||
*/ | ||
function (request) { | ||
IndexedDBDatabase.prototype.toSuccessObservable = function (request) { | ||
/* Transforming a IndexedDB success event in an RxJS Observable with true value */ | ||
return (/** @type {?} */ (rxjs_observable_fromEvent.fromEvent(request, 'success'))) | ||
.pipe(rxjs_operators.map(function () { return true; })); | ||
return rxjs_Observable.Observable.fromEvent(request, 'success').map(function () { return true; }); | ||
}; | ||
/** | ||
* Transforms a IndexedDB error event in an RxJS ErrorObservable | ||
* @param request The request to listen | ||
* @param error Optionnal details about the error's origin | ||
* @returns A RxJS ErrorObservable | ||
*/ | ||
/** | ||
* Transforms a IndexedDB error event in an RxJS ErrorObservable | ||
* @param {?} request The request to listen | ||
@@ -300,21 +285,16 @@ * @param {?=} error Optionnal details about the error's origin | ||
*/ | ||
IndexedDBDatabase.prototype.toErrorObservable = /** | ||
* Transforms a IndexedDB error event in an RxJS ErrorObservable | ||
* @param {?} request The request to listen | ||
* @param {?=} error Optionnal details about the error's origin | ||
* @return {?} A RxJS ErrorObservable | ||
*/ | ||
function (request, error) { | ||
IndexedDBDatabase.prototype.toErrorObservable = function (request, error) { | ||
if (error === void 0) { error = ""; } | ||
/* Transforming a IndexedDB error event in an RxJS ErrorObservable */ | ||
return (/** @type {?} */ (rxjs_observable_fromEvent.fromEvent(request, 'error'))) | ||
.pipe(rxjs_operators.mergeMap(function (event) { return rxjs_observable_throw._throw(new Error("IndexedDB " + error + " issue : " + request.error.message + ".")); })); | ||
return rxjs_Observable.Observable.fromEvent(request, 'error').mergeMap(function () { return rxjs_Observable.Observable.throw(new Error("IndexedDB " + error + " issue.")); }); | ||
}; | ||
IndexedDBDatabase.decorators = [ | ||
{ type: _angular_core.Injectable }, | ||
]; | ||
/** @nocollapse */ | ||
IndexedDBDatabase.ctorParameters = function () { return []; }; | ||
return IndexedDBDatabase; | ||
}(AsyncLocalDatabase)); | ||
IndexedDBDatabase.decorators = [ | ||
{ type: _angular_core.Injectable }, | ||
]; | ||
/** | ||
* @nocollapse | ||
*/ | ||
IndexedDBDatabase.ctorParameters = function () { return []; }; | ||
@@ -331,6 +311,2 @@ var __extends$1 = (undefined && undefined.__extends) || (function () { | ||
})(); | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
*/ | ||
var LocalStorageDatabase = (function (_super) { | ||
@@ -346,7 +322,2 @@ __extends$1(LocalStorageDatabase, _super); | ||
* Gets an item value in local storage | ||
* @param key The item's key | ||
* @returns The item's value if the key exists, null otherwise, wrapped in an RxJS Observable | ||
*/ | ||
/** | ||
* Gets an item value in local storage | ||
* @template T | ||
@@ -356,29 +327,16 @@ * @param {?} key The item's key | ||
*/ | ||
LocalStorageDatabase.prototype.getItem = /** | ||
* Gets an item value in local storage | ||
* @template T | ||
* @param {?} key The item's key | ||
* @return {?} The item's value if the key exists, null otherwise, wrapped in an RxJS Observable | ||
*/ | ||
function (key) { | ||
var /** @type {?} */ unparsedData = this.localStorage.getItem(key); | ||
var /** @type {?} */ parsedData = null; | ||
if (unparsedData != null) { | ||
LocalStorageDatabase.prototype.getItem = function (key) { | ||
var /** @type {?} */ data = this.localStorage.getItem(key); | ||
if (data != null) { | ||
try { | ||
parsedData = JSON.parse(unparsedData); | ||
data = JSON.parse(data); | ||
} | ||
catch (/** @type {?} */ error) { | ||
return rxjs_observable_throw._throw(new Error("Invalid data in localStorage.")); | ||
catch (error) { | ||
return rxjs_Observable.Observable.throw(new Error("Invalid data in localStorage.")); | ||
} | ||
} | ||
return rxjs_observable_of.of(parsedData); | ||
return rxjs_Observable.Observable.of(data); | ||
}; | ||
/** | ||
* Sets an item in local storage | ||
* @param key The item's key | ||
* @param data The item's value, must NOT be null or undefined | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Sets an item in local storage | ||
* @param {?} key The item's key | ||
@@ -388,54 +346,32 @@ * @param {?} data The item's value, must NOT be null or undefined | ||
*/ | ||
LocalStorageDatabase.prototype.setItem = /** | ||
* Sets an item in local storage | ||
* @param {?} key The item's key | ||
* @param {?} data The item's value, must NOT be null or undefined | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function (key, data) { | ||
LocalStorageDatabase.prototype.setItem = function (key, data) { | ||
this.localStorage.setItem(key, JSON.stringify(data)); | ||
return rxjs_observable_of.of(true); | ||
return rxjs_Observable.Observable.of(true); | ||
}; | ||
/** | ||
* Deletes an item in local storage | ||
* @param key The item's key | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Deletes an item in local storage | ||
* @param {?} key The item's key | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
LocalStorageDatabase.prototype.removeItem = /** | ||
* Deletes an item in local storage | ||
* @param {?} key The item's key | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function (key) { | ||
LocalStorageDatabase.prototype.removeItem = function (key) { | ||
this.localStorage.removeItem(key); | ||
return rxjs_observable_of.of(true); | ||
return rxjs_Observable.Observable.of(true); | ||
}; | ||
/** | ||
* Deletes all items from local storage | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Deletes all items from local storage | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
LocalStorageDatabase.prototype.clear = /** | ||
* Deletes all items from local storage | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function () { | ||
LocalStorageDatabase.prototype.clear = function () { | ||
this.localStorage.clear(); | ||
return rxjs_observable_of.of(true); | ||
return rxjs_Observable.Observable.of(true); | ||
}; | ||
LocalStorageDatabase.decorators = [ | ||
{ type: _angular_core.Injectable }, | ||
]; | ||
/** @nocollapse */ | ||
LocalStorageDatabase.ctorParameters = function () { return []; }; | ||
return LocalStorageDatabase; | ||
}(AsyncLocalDatabase)); | ||
LocalStorageDatabase.decorators = [ | ||
{ type: _angular_core.Injectable }, | ||
]; | ||
/** | ||
* @nocollapse | ||
*/ | ||
LocalStorageDatabase.ctorParameters = function () { return []; }; | ||
@@ -452,6 +388,2 @@ var __extends$2 = (undefined && undefined.__extends) || (function () { | ||
})(); | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
*/ | ||
var MockLocalDatabase = (function (_super) { | ||
@@ -466,7 +398,2 @@ __extends$2(MockLocalDatabase, _super); | ||
* Gets an item value in local storage | ||
* @param key The item's key | ||
* @returns The item's value if the key exists, null otherwise, wrapped in an RxJS Observable | ||
*/ | ||
/** | ||
* Gets an item value in local storage | ||
* @template T | ||
@@ -476,20 +403,8 @@ * @param {?} key The item's key | ||
*/ | ||
MockLocalDatabase.prototype.getItem = /** | ||
* Gets an item value in local storage | ||
* @template T | ||
* @param {?} key The item's key | ||
* @return {?} The item's value if the key exists, null otherwise, wrapped in an RxJS Observable | ||
*/ | ||
function (key) { | ||
var /** @type {?} */ rawData = this.localStorage.get(key); | ||
return rxjs_observable_of.of((rawData !== undefined) ? rawData : null); | ||
MockLocalDatabase.prototype.getItem = function (key) { | ||
var /** @type {?} */ data = this.localStorage.get(key); | ||
return rxjs_Observable.Observable.of((data !== undefined) ? data : null); | ||
}; | ||
/** | ||
* Sets an item in local storage | ||
* @param key The item's key | ||
* @param data The item's value, must NOT be null or undefined | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Sets an item in local storage | ||
* @param {?} key The item's key | ||
@@ -499,470 +414,83 @@ * @param {?} data The item's value, must NOT be null or undefined | ||
*/ | ||
MockLocalDatabase.prototype.setItem = /** | ||
* Sets an item in local storage | ||
* @param {?} key The item's key | ||
* @param {?} data The item's value, must NOT be null or undefined | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function (key, data) { | ||
MockLocalDatabase.prototype.setItem = function (key, data) { | ||
this.localStorage.set(key, data); | ||
return rxjs_observable_of.of(true); | ||
return rxjs_Observable.Observable.of(true); | ||
}; | ||
/** | ||
* Deletes an item in local storage | ||
* @param key The item's key | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Deletes an item in local storage | ||
* @param {?} key The item's key | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
MockLocalDatabase.prototype.removeItem = /** | ||
* Deletes an item in local storage | ||
* @param {?} key The item's key | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function (key) { | ||
MockLocalDatabase.prototype.removeItem = function (key) { | ||
this.localStorage.delete(key); | ||
return rxjs_observable_of.of(true); | ||
return rxjs_Observable.Observable.of(true); | ||
}; | ||
/** | ||
* Deletes all items from local storage | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Deletes all items from local storage | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
MockLocalDatabase.prototype.clear = /** | ||
* Deletes all items from local storage | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function () { | ||
MockLocalDatabase.prototype.clear = function () { | ||
this.localStorage.clear(); | ||
return rxjs_observable_of.of(true); | ||
return rxjs_Observable.Observable.of(true); | ||
}; | ||
MockLocalDatabase.decorators = [ | ||
{ type: _angular_core.Injectable }, | ||
]; | ||
/** @nocollapse */ | ||
MockLocalDatabase.ctorParameters = function () { return []; }; | ||
return MockLocalDatabase; | ||
}(AsyncLocalDatabase)); | ||
MockLocalDatabase.decorators = [ | ||
{ type: _angular_core.Injectable }, | ||
]; | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
* @nocollapse | ||
*/ | ||
/** | ||
* \@todo Add other JSON Schema validation features | ||
*/ | ||
var JSONValidator = (function () { | ||
function JSONValidator() { | ||
this.simpleTypes = ['string', 'number', 'boolean', 'object']; | ||
} | ||
/** | ||
* @param {?} value | ||
* @return {?} | ||
*/ | ||
JSONValidator.prototype.isObjectNotNull = /** | ||
* @param {?} value | ||
* @return {?} | ||
*/ | ||
function (value) { | ||
return (value !== null) && (typeof value === 'object'); | ||
}; | ||
/** | ||
* Validate a JSON data against a JSON Schema | ||
* @param data JSON data to validate | ||
* @param schema Subset of JSON Schema | ||
* @returns If data is valid : true, if it is invalid : false, and throws if the schema is invalid | ||
*/ | ||
/** | ||
* Validate a JSON data against a JSON Schema | ||
* @param {?} data JSON data to validate | ||
* @param {?} schema Subset of JSON Schema | ||
* @return {?} If data is valid : true, if it is invalid : false, and throws if the schema is invalid | ||
*/ | ||
JSONValidator.prototype.validate = /** | ||
* Validate a JSON data against a JSON Schema | ||
* @param {?} data JSON data to validate | ||
* @param {?} schema Subset of JSON Schema | ||
* @return {?} If data is valid : true, if it is invalid : false, and throws if the schema is invalid | ||
*/ | ||
function (data, schema) { | ||
if (!this.isObjectNotNull(schema)) { | ||
throw new Error("A schema must be an object (unlike spec, booleans are not supported to enforce strict types)."); | ||
} | ||
if ((!schema.hasOwnProperty('type') || schema.type === 'array' || schema.type === 'object') | ||
&& !schema.hasOwnProperty('properties') && !schema.hasOwnProperty('items')) { | ||
throw new Error("Each value must have a 'type' or 'properties' or 'items', to enforce strict types."); | ||
} | ||
if (schema.hasOwnProperty('type') && !this.validateType(data, schema)) { | ||
return false; | ||
} | ||
if (schema.hasOwnProperty('items') && !this.validateItems(data, schema)) { | ||
return false; | ||
} | ||
if (schema.hasOwnProperty('properties')) { | ||
if (schema.hasOwnProperty('required') && !this.validateRequired(data, schema)) { | ||
return false; | ||
} | ||
if (!this.validateProperties(data, schema)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
}; | ||
/** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
JSONValidator.prototype.validateProperties = /** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
function (data, schema) { | ||
if (!this.isObjectNotNull(data)) { | ||
return false; | ||
} | ||
if (!schema.properties || !this.isObjectNotNull(schema.properties)) { | ||
throw new Error("'properties' must be a schema object."); | ||
} | ||
/** | ||
* Check if the object doesn't have more properties than expected | ||
* Equivalent of additionalProperties: false | ||
*/ | ||
if (Object.keys(schema.properties).length !== Object.keys(data).length) { | ||
return false; | ||
} | ||
/* Recursively validate all properties */ | ||
for (var /** @type {?} */ property in schema.properties) { | ||
if (schema.properties.hasOwnProperty(property) && data.hasOwnProperty(property)) { | ||
if (!this.validate(data[property], schema.properties[property])) { | ||
return false; | ||
} | ||
} | ||
} | ||
return true; | ||
}; | ||
/** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
JSONValidator.prototype.validateRequired = /** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
function (data, schema) { | ||
if (!this.isObjectNotNull(data)) { | ||
return false; | ||
} | ||
if (!Array.isArray(schema.required)) { | ||
throw new Error("'required' field must be an array. Note that since JSON Schema draft 6, booleans are not supported anymore."); | ||
} | ||
for (var _i = 0, _a = schema.required; _i < _a.length; _i++) { | ||
var requiredProp = _a[_i]; | ||
if (typeof requiredProp !== 'string') { | ||
throw new Error("'required' array must contain strings only."); | ||
} | ||
/* Checks if the property is present in the schema 'properties' */ | ||
if (!schema.properties || !schema.properties.hasOwnProperty(requiredProp)) { | ||
throw new Error("'required' properties must be described in 'properties' too."); | ||
} | ||
/* Checks if the property is present in the data */ | ||
if (!data.hasOwnProperty(requiredProp)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
}; | ||
/** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
JSONValidator.prototype.validateType = /** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
function (data, schema) { | ||
if (Array.isArray(schema.type)) { | ||
return this.validateTypeList(data, schema); | ||
} | ||
if (typeof schema.type !== 'string') { | ||
throw new Error("'type' must be a string (arrays of types are not supported yet)."); | ||
} | ||
if ((schema.type === 'null') && (data !== null)) { | ||
return false; | ||
} | ||
if ((this.simpleTypes.indexOf(schema.type) !== -1) && (typeof data !== schema.type)) { | ||
return false; | ||
} | ||
if ((schema.type === 'integer') && ((typeof data !== 'number') || !Number.isInteger(data))) { | ||
return false; | ||
} | ||
return true; | ||
}; | ||
/** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
JSONValidator.prototype.validateTypeList = /** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
function (data, schema) { | ||
var /** @type {?} */ types = /** @type {?} */ (schema.type); | ||
var /** @type {?} */ typesTests = []; | ||
for (var _i = 0, types_1 = types; _i < types_1.length; _i++) { | ||
var type = types_1[_i]; | ||
typesTests.push(this.validateType(data, { type: type })); | ||
} | ||
return (typesTests.indexOf(true) !== -1); | ||
}; | ||
/** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
JSONValidator.prototype.validateItems = /** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
function (data, schema) { | ||
if (!Array.isArray(data)) { | ||
return false; | ||
} | ||
if (Array.isArray(schema.items)) { | ||
return this.validateItemsList(data, schema); | ||
} | ||
if (!schema.items || !this.isObjectNotNull(schema.items)) { | ||
throw new Error("'items' must be a schema object."); | ||
} | ||
for (var _i = 0, data_1 = data; _i < data_1.length; _i++) { | ||
var value = data_1[_i]; | ||
if (!this.validate(value, schema.items)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
}; | ||
/** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
JSONValidator.prototype.validateItemsList = /** | ||
* @param {?} data | ||
* @param {?} schema | ||
* @return {?} | ||
*/ | ||
function (data, schema) { | ||
var /** @type {?} */ items = /** @type {?} */ (schema.items); | ||
if (data.length !== items.length) { | ||
return false; | ||
} | ||
for (var /** @type {?} */ i = 0; i < items.length; i += 1) { | ||
if (!this.validate(data[i], items[i])) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
}; | ||
return JSONValidator; | ||
}()); | ||
MockLocalDatabase.ctorParameters = function () { return []; }; | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
*/ | ||
/** | ||
* @record | ||
*/ | ||
var AsyncLocalStorage = (function () { | ||
function AsyncLocalStorage(database, jsonValidator) { | ||
this.database = database; | ||
this.jsonValidator = jsonValidator; | ||
this.getItemOptionsDefault = { | ||
schema: null | ||
}; | ||
} | ||
/** | ||
* Gets an item value in local storage | ||
* @param key The item's key | ||
* @returns The item's value if the key exists, null otherwise, wrapped in an RxJS Observable | ||
*/ | ||
/** | ||
* Gets an item value in local storage | ||
* @template T | ||
* @param {?} key The item's key | ||
* @param {?=} options | ||
* @return {?} The item's value if the key exists, null otherwise, wrapped in an RxJS Observable | ||
*/ | ||
AsyncLocalStorage.prototype.getItem = /** | ||
* Gets an item value in local storage | ||
* @template T | ||
* @param {?} key The item's key | ||
* @param {?=} options | ||
* @return {?} The item's value if the key exists, null otherwise, wrapped in an RxJS Observable | ||
*/ | ||
function (key, options) { | ||
var _this = this; | ||
if (options === void 0) { options = this.getItemOptionsDefault; } | ||
return this.database.getItem(key).pipe(/* Validate data upon a json schema if requested */ | ||
rxjs_operators.mergeMap(function (data) { | ||
if (options.schema && data !== null) { | ||
var /** @type {?} */ validation = true; | ||
try { | ||
validation = _this.jsonValidator.validate(data, options.schema); | ||
} | ||
catch (/** @type {?} */ error) { | ||
return rxjs_observable_throw._throw(error); | ||
} | ||
if (!validation) { | ||
return rxjs_observable_throw._throw(new Error("JSON invalid")); | ||
} | ||
} | ||
return rxjs_observable_of.of(data); | ||
})); | ||
}; | ||
/** | ||
* Sets an item in local storage | ||
* @param key The item's key | ||
* @param data The item's value, must NOT be null or undefined | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Sets an item in local storage | ||
* @param {?} key The item's key | ||
* @param {?} data The item's value, must NOT be null or undefined | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
AsyncLocalStorage.prototype.setItem = /** | ||
* Sets an item in local storage | ||
* @param {?} key The item's key | ||
* @param {?} data The item's value, must NOT be null or undefined | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function (key, data) { | ||
return this.database.setItem(key, data); | ||
}; | ||
/** | ||
* Deletes an item in local storage | ||
* @param key The item's key | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Deletes an item in local storage | ||
* @param {?} key The item's key | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
AsyncLocalStorage.prototype.removeItem = /** | ||
* Deletes an item in local storage | ||
* @param {?} key The item's key | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function (key) { | ||
return this.database.removeItem(key); | ||
}; | ||
/** | ||
* Deletes all items from local storage | ||
* @returns An RxJS Observable to wait the end of the operation | ||
*/ | ||
/** | ||
* Deletes all items from local storage | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
AsyncLocalStorage.prototype.clear = /** | ||
* Deletes all items from local storage | ||
* @return {?} An RxJS Observable to wait the end of the operation | ||
*/ | ||
function () { | ||
return this.database.clear(); | ||
}; | ||
AsyncLocalStorage.decorators = [ | ||
{ type: _angular_core.Injectable }, | ||
]; | ||
/** @nocollapse */ | ||
AsyncLocalStorage.ctorParameters = function () { return [ | ||
{ type: AsyncLocalDatabase, }, | ||
{ type: JSONValidator, }, | ||
]; }; | ||
return AsyncLocalStorage; | ||
}()); | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
*/ | ||
/** | ||
* @param {?} platformId | ||
* @return {?} | ||
*/ | ||
function databaseFactory(platformId) { | ||
function asyncLocalStorageFactory(platformId) { | ||
var /** @type {?} */ database; | ||
if (_angular_common.isPlatformBrowser(platformId) && ('indexedDB' in window) && (indexedDB !== undefined) && (indexedDB !== null)) { | ||
/* Try with IndexedDB in modern browsers */ | ||
return new IndexedDBDatabase(); | ||
database = new IndexedDBDatabase(); | ||
} | ||
else if (_angular_common.isPlatformBrowser(platformId) && ('localStorage' in window) && (localStorage !== undefined) && (localStorage !== null)) { | ||
/* Try with localStorage in old browsers (IE9) */ | ||
return new LocalStorageDatabase(); | ||
database = new LocalStorageDatabase(); | ||
} | ||
else { | ||
/* Fake database for server-side rendering (Universal) */ | ||
return new MockLocalDatabase(); | ||
database = new MockLocalDatabase(); | ||
} | ||
return new AsyncLocalStorage(database); | ||
} | ||
var AsyncLocalStorageModule = (function () { | ||
function AsyncLocalStorageModule() { | ||
} | ||
AsyncLocalStorageModule.decorators = [ | ||
{ type: _angular_core.NgModule, args: [{ | ||
providers: [ | ||
JSONValidator, | ||
{ | ||
provide: AsyncLocalDatabase, | ||
useFactory: databaseFactory, | ||
deps: [_angular_core.PLATFORM_ID] | ||
}, | ||
AsyncLocalStorage, | ||
] | ||
},] }, | ||
]; | ||
/** @nocollapse */ | ||
AsyncLocalStorageModule.ctorParameters = function () { return []; }; | ||
return AsyncLocalStorageModule; | ||
}()); | ||
AsyncLocalStorageModule.decorators = [ | ||
{ type: _angular_core.NgModule, args: [{ | ||
providers: [ | ||
{ | ||
provide: AsyncLocalStorage, | ||
useFactory: asyncLocalStorageFactory, | ||
deps: [_angular_core.PLATFORM_ID] | ||
} | ||
] | ||
},] }, | ||
]; | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
* @nocollapse | ||
*/ | ||
AsyncLocalStorageModule.ctorParameters = function () { return []; }; | ||
/** | ||
* @fileoverview added by tsickle | ||
* @suppress {checkTypes} checked by tsc | ||
*/ | ||
/** | ||
* Generated bundle index. Do not edit. | ||
*/ | ||
exports.AsyncLocalDatabase = AsyncLocalDatabase; | ||
exports.IndexedDBDatabase = IndexedDBDatabase; | ||
exports.LocalStorageDatabase = LocalStorageDatabase; | ||
exports.MockLocalDatabase = MockLocalDatabase; | ||
exports.JSONValidator = JSONValidator; | ||
exports.AsyncLocalStorage = AsyncLocalStorage; | ||
exports.AsyncLocalStorageModule = AsyncLocalStorageModule; | ||
exports.ɵa = databaseFactory; | ||
exports.ɵa = asyncLocalStorageFactory; | ||
exports.ɵb = AsyncLocalDatabase; | ||
@@ -969,0 +497,0 @@ Object.defineProperty(exports, '__esModule', { value: true }); |
@@ -1,2 +0,2 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@angular/core"),require("rxjs/ReplaySubject"),require("rxjs/operators"),require("rxjs/observable/fromEvent"),require("rxjs/observable/of"),require("rxjs/observable/throw"),require("rxjs/observable/race"),require("@angular/common")):"function"==typeof define&&define.amd?define(["exports","@angular/core","rxjs/ReplaySubject","rxjs/operators","rxjs/observable/fromEvent","rxjs/observable/of","rxjs/observable/throw","rxjs/observable/race","@angular/common"],t):t(e.angularAsyncLocalStorage=e.angularAsyncLocalStorage||{},e.ng.core,e.Rx,e.Rx.operators,e.Rx.Observable,e.Rx.Observable,e.Rx.Observable,e.Rx.Observable,e.ng.common)}(this,function(e,t,r,o,n,a,i,s,u){"use strict";function p(e){return u.isPlatformBrowser(e)&&"indexedDB"in window&&void 0!==indexedDB&&null!==indexedDB?new f:u.isPlatformBrowser(e)&&"localStorage"in window&&void 0!==localStorage&&null!==localStorage?new b:new d}var c=function(){return function(){}}(),l=function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])};return function(t,r){function o(){this.constructor=t}e(t,r),t.prototype=null===r?Object.create(r):(o.prototype=r.prototype,new o)}}(),f=function(e){function u(){var t=e.call(this)||this;return t.dbName="ngStorage",t.objectStoreName="localStorage",t.keyPath="key",t.dataPath="value",t.database=new r.ReplaySubject,t.connect(),t}return l(u,e),u.prototype.getItem=function(e){var t=this;return this.transaction().pipe(o.map(function(t){return t.get(e)}),o.mergeMap(function(e){var r=n.fromEvent(e,"success").pipe(o.map(function(e){return e.target.result}),o.map(function(e){return e&&t.dataPath in e?e[t.dataPath]:null}));return s.race(r,t.toErrorObservable(e,"getter")).pipe(o.first())}),o.first())},u.prototype.setItem=function(e,t){var r=this;return null==t?a.of(!0):this.getItem(e).pipe(o.map(function(e){return null==e?"add":"put"}),o.mergeMap(function(n){return r.transaction("readwrite").pipe(o.mergeMap(function(a){var i;switch(n){case"add":i=a.add((u={},u[r.dataPath]=t,u),e);break;case"put":default:i=a.put((p={},p[r.dataPath]=t,p),e)}return s.race(r.toSuccessObservable(i),r.toErrorObservable(i,"setter")).pipe(o.first());var u,p}))}),o.first())},u.prototype.removeItem=function(e){var t=this;return this.getItem(e).pipe(o.mergeMap(function(r){return null!=r?t.transaction("readwrite").pipe(o.mergeMap(function(r){var n=r.delete(e);return s.race(t.toSuccessObservable(n),t.toErrorObservable(n,"remover")).pipe(o.first())})):a.of(!0)}),o.first())},u.prototype.clear=function(){var e=this;return this.transaction("readwrite").pipe(o.mergeMap(function(t){var r=t.clear();return s.race(e.toSuccessObservable(r),e.toErrorObservable(r,"clearer")).pipe(o.first())}),o.first())},u.prototype.connect=function(){var e=this,t=indexedDB.open(this.dbName);n.fromEvent(t,"upgradeneeded").pipe(o.first()).subscribe(function(t){var r=t.target.result;r.objectStoreNames.contains(e.objectStoreName)||r.createObjectStore(e.objectStoreName)});var r=n.fromEvent(t,"success");s.race(r,this.toErrorObservable(t,"connection")).pipe(o.first()).subscribe(function(t){e.database.next(t.target.result)},function(t){e.database.error(t)})},u.prototype.transaction=function(e){var t=this;return void 0===e&&(e="readonly"),this.database.pipe(o.map(function(r){return r.transaction([t.objectStoreName],e).objectStore(t.objectStoreName)}))},u.prototype.toSuccessObservable=function(e){return n.fromEvent(e,"success").pipe(o.map(function(){return!0}))},u.prototype.toErrorObservable=function(e,t){return void 0===t&&(t=""),n.fromEvent(e,"error").pipe(o.mergeMap(function(r){return i._throw(new Error("IndexedDB "+t+" issue : "+e.error.message+"."))}))},u.decorators=[{type:t.Injectable}],u.ctorParameters=function(){return[]},u}(c),y=function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])};return function(t,r){function o(){this.constructor=t}e(t,r),t.prototype=null===r?Object.create(r):(o.prototype=r.prototype,new o)}}(),b=function(e){function r(){var t=null!==e&&e.apply(this,arguments)||this;return t.localStorage=localStorage,t}return y(r,e),r.prototype.getItem=function(e){var t=this.localStorage.getItem(e),r=null;if(null!=t)try{r=JSON.parse(t)}catch(e){return i._throw(new Error("Invalid data in localStorage."))}return a.of(r)},r.prototype.setItem=function(e,t){return this.localStorage.setItem(e,JSON.stringify(t)),a.of(!0)},r.prototype.removeItem=function(e){return this.localStorage.removeItem(e),a.of(!0)},r.prototype.clear=function(){return this.localStorage.clear(),a.of(!0)},r.decorators=[{type:t.Injectable}],r.ctorParameters=function(){return[]},r}(c),h=function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])};return function(t,r){function o(){this.constructor=t}e(t,r),t.prototype=null===r?Object.create(r):(o.prototype=r.prototype,new o)}}(),d=function(e){function r(){var t=null!==e&&e.apply(this,arguments)||this;return t.localStorage=new Map,t}return h(r,e),r.prototype.getItem=function(e){var t=this.localStorage.get(e);return a.of(void 0!==t?t:null)},r.prototype.setItem=function(e,t){return this.localStorage.set(e,t),a.of(!0)},r.prototype.removeItem=function(e){return this.localStorage.delete(e),a.of(!0)},r.prototype.clear=function(){return this.localStorage.clear(),a.of(!0)},r.decorators=[{type:t.Injectable}],r.ctorParameters=function(){return[]},r}(c),m=function(){function e(){this.simpleTypes=["string","number","boolean","object"]}return e.prototype.isObjectNotNull=function(e){return null!==e&&"object"==typeof e},e.prototype.validate=function(e,t){if(!this.isObjectNotNull(t))throw new Error("A schema must be an object (unlike spec, booleans are not supported to enforce strict types).");if(!(t.hasOwnProperty("type")&&"array"!==t.type&&"object"!==t.type||t.hasOwnProperty("properties")||t.hasOwnProperty("items")))throw new Error("Each value must have a 'type' or 'properties' or 'items', to enforce strict types.");if(t.hasOwnProperty("type")&&!this.validateType(e,t))return!1;if(t.hasOwnProperty("items")&&!this.validateItems(e,t))return!1;if(t.hasOwnProperty("properties")){if(t.hasOwnProperty("required")&&!this.validateRequired(e,t))return!1;if(!this.validateProperties(e,t))return!1}return!0},e.prototype.validateProperties=function(e,t){if(!this.isObjectNotNull(e))return!1;if(!t.properties||!this.isObjectNotNull(t.properties))throw new Error("'properties' must be a schema object.");if(Object.keys(t.properties).length!==Object.keys(e).length)return!1;for(var r in t.properties)if(t.properties.hasOwnProperty(r)&&e.hasOwnProperty(r)&&!this.validate(e[r],t.properties[r]))return!1;return!0},e.prototype.validateRequired=function(e,t){if(!this.isObjectNotNull(e))return!1;if(!Array.isArray(t.required))throw new Error("'required' field must be an array. Note that since JSON Schema draft 6, booleans are not supported anymore.");for(var r=0,o=t.required;r<o.length;r++){var n=o[r];if("string"!=typeof n)throw new Error("'required' array must contain strings only.");if(!t.properties||!t.properties.hasOwnProperty(n))throw new Error("'required' properties must be described in 'properties' too.");if(!e.hasOwnProperty(n))return!1}return!0},e.prototype.validateType=function(e,t){if(Array.isArray(t.type))return this.validateTypeList(e,t);if("string"!=typeof t.type)throw new Error("'type' must be a string (arrays of types are not supported yet).");return("null"!==t.type||null===e)&&((-1===this.simpleTypes.indexOf(t.type)||typeof e===t.type)&&!!("integer"!==t.type||"number"==typeof e&&Number.isInteger(e)))},e.prototype.validateTypeList=function(e,t){for(var r=[],o=0,n=t.type;o<n.length;o++){var a=n[o];r.push(this.validateType(e,{type:a}))}return-1!==r.indexOf(!0)},e.prototype.validateItems=function(e,t){if(!Array.isArray(e))return!1;if(Array.isArray(t.items))return this.validateItemsList(e,t);if(!t.items||!this.isObjectNotNull(t.items))throw new Error("'items' must be a schema object.");for(var r=0,o=e;r<o.length;r++){var n=o[r];if(!this.validate(n,t.items))return!1}return!0},e.prototype.validateItemsList=function(e,t){var r=t.items;if(e.length!==r.length)return!1;for(var o=0;o<r.length;o+=1)if(!this.validate(e[o],r[o]))return!1;return!0},e}(),v=function(){function e(e,t){this.database=e,this.jsonValidator=t,this.getItemOptionsDefault={schema:null}}return e.prototype.getItem=function(e,t){var r=this;return void 0===t&&(t=this.getItemOptionsDefault),this.database.getItem(e).pipe(o.mergeMap(function(e){if(t.schema&&null!==e){var o=!0;try{o=r.jsonValidator.validate(e,t.schema)}catch(e){return i._throw(e)}if(!o)return i._throw(new Error("JSON invalid"))}return a.of(e)}))},e.prototype.setItem=function(e,t){return this.database.setItem(e,t)},e.prototype.removeItem=function(e){return this.database.removeItem(e)},e.prototype.clear=function(){return this.database.clear()},e.decorators=[{type:t.Injectable}],e.ctorParameters=function(){return[{type:c},{type:m}]},e}(),g=function(){function e(){}return e.decorators=[{type:t.NgModule,args:[{providers:[m,{provide:c,useFactory:p,deps:[t.PLATFORM_ID]},v]}]}],e.ctorParameters=function(){return[]},e}();e.AsyncLocalDatabase=c,e.IndexedDBDatabase=f,e.LocalStorageDatabase=b,e.MockLocalDatabase=d,e.JSONValidator=m,e.AsyncLocalStorage=v,e.AsyncLocalStorageModule=g,e.ɵa=p,Object.defineProperty(e,"__esModule",{value:!0})}); | ||
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("@angular/core"),require("@angular/common"),require("rxjs/Observable"),require("rxjs/ReplaySubject"),require("rxjs/add/operator/map"),require("rxjs/add/operator/mergeMap"),require("rxjs/add/operator/pluck"),require("rxjs/add/operator/first"),require("rxjs/add/observable/fromEvent"),require("rxjs/add/observable/merge"),require("rxjs/add/observable/throw"),require("rxjs/add/observable/of")):"function"==typeof define&&define.amd?define(["exports","@angular/core","@angular/common","rxjs/Observable","rxjs/ReplaySubject","rxjs/add/operator/map","rxjs/add/operator/mergeMap","rxjs/add/operator/pluck","rxjs/add/operator/first","rxjs/add/observable/fromEvent","rxjs/add/observable/merge","rxjs/add/observable/throw","rxjs/add/observable/of"],r):r(e.angularAsyncLocalStorage=e.angularAsyncLocalStorage||{},e.ng.core,e.ng.common,e.Rx,e.Rx)}(this,function(e,r,t,o,n){"use strict";function a(e){var r;return r=t.isPlatformBrowser(e)&&"indexedDB"in window&&void 0!==indexedDB&&null!==indexedDB?new i:t.isPlatformBrowser(e)&&"localStorage"in window&&void 0!==localStorage&&null!==localStorage?new p:new b,new c(r)}var s=function(){function e(){}return e.prototype.getItem=function(e){},e.prototype.setItem=function(e,r){},e.prototype.removeItem=function(e){},e.prototype.clear=function(){},e}(),c=function(){function e(e){this.database=e}return e.prototype.getItem=function(e){return this.database.getItem(e)},e.prototype.setItem=function(e,r){return this.database.setItem(e,r)},e.prototype.removeItem=function(e){return this.database.removeItem(e)},e.prototype.clear=function(){return this.database.clear()},e}();c.decorators=[{type:r.Injectable}],c.ctorParameters=function(){return[{type:s}]};var u=function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,r){e.__proto__=r}||function(e,r){for(var t in r)r.hasOwnProperty(t)&&(e[t]=r[t])};return function(r,t){function o(){this.constructor=r}e(r,t),r.prototype=null===t?Object.create(t):(o.prototype=t.prototype,new o)}}(),i=function(e){function r(){var r=e.call(this)||this;return r.dbName="ngStorage",r.objectStoreName="localStorage",r.keyPath="key",r.dataPath="value",r.database=new n.ReplaySubject,r.connect(),r}return u(r,e),r.prototype.getItem=function(e){var r=this;return this.transaction().map(function(r){return r.get(e)}).mergeMap(function(e){var t=o.Observable.fromEvent(e,"success").pluck("target","result").map(function(e){return e?e[r.dataPath]:null});return o.Observable.merge(t,r.toErrorObservable(e,"getter")).first()}).first()},r.prototype.setItem=function(e,r){var t=this;return null==r?o.Observable.of(!0).first():this.getItem(e).map(function(e){return null==e?"add":"put"}).mergeMap(function(n){return t.transaction("readwrite").mergeMap(function(a){var s;switch(n){case"add":s=a.add((c={},c[t.dataPath]=r,c),e);break;case"put":default:s=a.put((u={},u[t.dataPath]=r,u),e)}return o.Observable.merge(t.toSuccessObservable(s),t.toErrorObservable(s,"setter")).first();var c,u})}).first()},r.prototype.removeItem=function(e){var r=this;return this.getItem(e).mergeMap(function(t){return null!=t?r.transaction("readwrite").mergeMap(function(t){var n=t.delete(e);return o.Observable.merge(r.toSuccessObservable(n),r.toErrorObservable(n,"remover")).first()}):o.Observable.of(!0).first()}).first()},r.prototype.clear=function(){var e=this;return this.transaction("readwrite").mergeMap(function(r){var t=r.clear();return o.Observable.merge(e.toSuccessObservable(t),e.toErrorObservable(t,"clearer")).first()}).first()},r.prototype.connect=function(){var e=this,r=indexedDB.open(this.dbName);o.Observable.fromEvent(r,"upgradeneeded").first().subscribe(function(r){var t=r.target.result;t.objectStoreNames.contains(e.objectStoreName)||t.createObjectStore(e.objectStoreName)});var t=o.Observable.fromEvent(r,"success");o.Observable.merge(t,this.toErrorObservable(r,"connection")).first().subscribe(function(r){e.database.next(r.target.result)},function(r){e.database.error(r)})},r.prototype.transaction=function(e){var r=this;return void 0===e&&(e="readonly"),this.database.map(function(t){return t.transaction([r.objectStoreName],e).objectStore(r.objectStoreName)})},r.prototype.toSuccessObservable=function(e){return o.Observable.fromEvent(e,"success").map(function(){return!0})},r.prototype.toErrorObservable=function(e,r){return void 0===r&&(r=""),o.Observable.fromEvent(e,"error").mergeMap(function(){return o.Observable.throw(new Error("IndexedDB "+r+" issue."))})},r}(s);i.decorators=[{type:r.Injectable}],i.ctorParameters=function(){return[]};var l=function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,r){e.__proto__=r}||function(e,r){for(var t in r)r.hasOwnProperty(t)&&(e[t]=r[t])};return function(r,t){function o(){this.constructor=r}e(r,t),r.prototype=null===t?Object.create(t):(o.prototype=t.prototype,new o)}}(),p=function(e){function r(){var r=null!==e&&e.apply(this,arguments)||this;return r.localStorage=localStorage,r}return l(r,e),r.prototype.getItem=function(e){var r=this.localStorage.getItem(e);if(null!=r)try{r=JSON.parse(r)}catch(e){return o.Observable.throw(new Error("Invalid data in localStorage."))}return o.Observable.of(r)},r.prototype.setItem=function(e,r){return this.localStorage.setItem(e,JSON.stringify(r)),o.Observable.of(!0)},r.prototype.removeItem=function(e){return this.localStorage.removeItem(e),o.Observable.of(!0)},r.prototype.clear=function(){return this.localStorage.clear(),o.Observable.of(!0)},r}(s);p.decorators=[{type:r.Injectable}],p.ctorParameters=function(){return[]};var f=function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,r){e.__proto__=r}||function(e,r){for(var t in r)r.hasOwnProperty(t)&&(e[t]=r[t])};return function(r,t){function o(){this.constructor=r}e(r,t),r.prototype=null===t?Object.create(t):(o.prototype=t.prototype,new o)}}(),b=function(e){function r(){var r=null!==e&&e.apply(this,arguments)||this;return r.localStorage=new Map,r}return f(r,e),r.prototype.getItem=function(e){var r=this.localStorage.get(e);return o.Observable.of(void 0!==r?r:null)},r.prototype.setItem=function(e,r){return this.localStorage.set(e,r),o.Observable.of(!0)},r.prototype.removeItem=function(e){return this.localStorage.delete(e),o.Observable.of(!0)},r.prototype.clear=function(){return this.localStorage.clear(),o.Observable.of(!0)},r}(s);b.decorators=[{type:r.Injectable}],b.ctorParameters=function(){return[]};var d=function(){return function(){}}();d.decorators=[{type:r.NgModule,args:[{providers:[{provide:c,useFactory:a,deps:[r.PLATFORM_ID]}]}]}],d.ctorParameters=function(){return[]},e.AsyncLocalStorage=c,e.AsyncLocalStorageModule=d,e.ɵa=a,e.ɵb=s,Object.defineProperty(e,"__esModule",{value:!0})}); | ||
//# sourceMappingURL=angular-async-local-storage.umd.min.js.map |
@@ -1,8 +0,2 @@ | ||
export { JSONSchema, JSONSchemaType } from './src/service/validation/json-schema'; | ||
export { AsyncLocalDatabase } from './src/service/databases/async-local-database'; | ||
export { IndexedDBDatabase } from './src/service/databases/indexeddb-database'; | ||
export { LocalStorageDatabase } from './src/service/databases/localstorage-database'; | ||
export { MockLocalDatabase } from './src/service/databases/mock-local-database'; | ||
export { JSONValidator } from './src/service/validation/json-validator'; | ||
export { ALSGetItemOptions, AsyncLocalStorage } from './src/service/lib.service'; | ||
export { AsyncLocalStorage } from './src/service/lib.service'; | ||
export { AsyncLocalStorageModule } from './src/module'; |
{ | ||
"name": "angular-async-local-storage", | ||
"version": "3.1.4", | ||
"version": "4.0.0", | ||
"description": "Efficient local storage module for Angular : simple API based on native localStorage API, but internally stored via the asynchronous IndexedDB API for performance, and wrapped in RxJS observables to be homogeneous with other Angular modules.", | ||
@@ -13,8 +13,4 @@ "main": "./bundles/angular-async-local-storage.umd.js", | ||
"angular", | ||
"angular2", | ||
"angular 2", | ||
"angular4", | ||
"angular 4", | ||
"angular5", | ||
"angular 5", | ||
"localstorage", | ||
@@ -56,17 +52,17 @@ "local storage" | ||
"lint": "tslint ./src/**/*.ts -t verbose", | ||
"release": "standard-version" | ||
"release": "standard-version", | ||
"reinstall": "rimraf node_modules && npm install", | ||
"publish": "npm publish dist --tag lts" | ||
}, | ||
"dependencies": {}, | ||
"peerDependencies": { | ||
"@angular/core": ">=5.0.0 <6.0.0", | ||
"@angular/common": ">=5.0.0 <6.0.0", | ||
"rxjs": "^5.5.2" | ||
"@angular/core": ">=4.0.0 <5.0.0", | ||
"@angular/common": ">=4.0.0 <5.0.0" | ||
}, | ||
"devDependencies": { | ||
"@angular/common": "^5.0.3", | ||
"@angular/compiler": "^5.0.3", | ||
"@angular/compiler-cli": "^5.0.3", | ||
"@angular/core": "^5.0.3", | ||
"@angular/platform-browser": "^5.0.3", | ||
"@angular/platform-browser-dynamic": "^5.0.3", | ||
"@angular/common": "^4.4.6", | ||
"@angular/compiler": "^4.4.6", | ||
"@angular/compiler-cli": "^4.4.6", | ||
"@angular/core": "^4.4.6", | ||
"@angular/platform-browser": "^4.4.6", | ||
"@angular/platform-browser-dynamic": "^4.4.6", | ||
"@types/jasmine": "2.5.36", | ||
@@ -83,6 +79,4 @@ "@types/node": "^6.0.46", | ||
"karma-coverage": "^1.1.1", | ||
"karma-edge-launcher": "^0.4.2", | ||
"karma-firefox-launcher": "^1.0.1", | ||
"karma-html-reporter": "^0.2.7", | ||
"karma-ie-launcher": "^1.0.0", | ||
"karma-jasmine": "^1.1.0", | ||
@@ -99,9 +93,9 @@ "karma-jasmine-html-reporter": "^0.2.2", | ||
"rollup-plugin-uglify": "^2.0.1", | ||
"rxjs": "^5.5.2", | ||
"rxjs": "^5.0.1", | ||
"standard-version": "^4.0.0", | ||
"systemjs": "^0.19.40", | ||
"tslint": "^4.4.2", | ||
"typescript": "~2.4.2", | ||
"typescript": "~2.3.4", | ||
"zone.js": "^0.8.4" | ||
} | ||
} |
108
README.md
# Async local storage for Angular | ||
Efficient local storage module for Angular : | ||
- **simplicity** : based on native `localStorage` API and automatic JSON stringify/parse, | ||
- **simple** : based on native `localStorage` API, | ||
- **perfomance** : internally stored via the asynchronous `IndexedDB` API, | ||
- **Angular-like** : wrapped in RxJS `Observables`, | ||
- **security** : validate data with a JSON Schema, | ||
- **extensibility** : add your own storage. | ||
- **Angular-like** : wrapped in RxJS `Observables`. | ||
## Angular onsite training | ||
The author of this library organizes Angular courses (based in Paris (France), but open to travel). You can find [details here](https://formationjavascript.com/formation-angular/) (in French). | ||
## Why this module ? | ||
@@ -41,7 +35,3 @@ | ||
```bash | ||
# For Angular 5 : | ||
npm install angular-async-local-storage | ||
# For Angular 4 and TypeScript >= 2.3 : | ||
npm install angular-async-local-storage@2 | ||
``` | ||
@@ -116,35 +106,7 @@ | ||
As any data can be stored, you can type your data. | ||
But don't forget it's client-side storage : **always check the data**, as it could have been forged or deleted. | ||
### Checking data | ||
Don't forget it's client-side storage : **always check the data**, as it could have been forged or deleted. | ||
Starting with *version 3.1*, you can use a [JSON Schema](http://json-schema.org/) to validate the data. | ||
```typescript | ||
import { JSONSchema } from 'angular-async-local-storage'; | ||
const schema: JSONSchema = { | ||
properties: { | ||
firstName: { type: 'string' }, | ||
lastName: { type: 'string' } | ||
}, | ||
required: ['firstName', 'lastName'] | ||
}; | ||
this.localStorage.getItem<User>('user', { schema }).subscribe((user) => { | ||
// Called if data is valid or null | ||
}, (error) => { | ||
// Called if data is invalid | ||
}); | ||
``` | ||
Note : last draft of JSON Schema is used (draft 7 at this time), | ||
but we don't support all validation features yet. Just follow the interface. | ||
Contributions are welcome to add more features. | ||
Note : as the goal is validation, types are enforced : each value MUST have either `type` or `properties` or `items`. | ||
### Notes | ||
- Not finding an item is not an error, it succeeds but returns `null`. | ||
Not finding an item is not an error, it succeeds but returns `null`. | ||
@@ -157,3 +119,3 @@ ```typescript | ||
- Errors are unlikely to happen, but in an app it's better to catch any potential error. | ||
Errors are unlikely to happen, but in an app it's better to catch any potential error. | ||
@@ -168,17 +130,14 @@ ```typescript | ||
- You *DO* need to subscribe, even if you don't have something specific to do after writing in local storage (because it's how RxJS Observables work). | ||
You *DO* need to subscribe, even if you don't have something specific to do after writing in local storage (because it's how RxJS Observables work). | ||
- You do *NOT* need to unsubscribe : the observable autocompletes (like in the `HttpClient` service). | ||
You do *NOT* need to unsubscribe : the observable autocompletes (like in the `HttpClient` service). | ||
- When reading data, you'll only get one value : the observable is here for asynchronicity but is not meant to | ||
emit again when the stored data will changed. And it's normal : if app data change, it's the role of your app | ||
to keep track of it, not of this lib. See [#16](https://github.com/cyrilletuzi/angular-async-local-storage/issues/16) | ||
for more context and [#4](https://github.com/cyrilletuzi/angular-async-local-storage/issues/4) | ||
for an example. | ||
## Angular support | ||
The last version of this library requires **Angular 5**. | ||
The last version of this library requires **Angular 4+** and **TypeScript 2.3+**. | ||
If you need support for previous versions of Angular, stay on older versions, like mentionned in Getting started. | ||
If you need Angular 2 support, stay on version 1 : | ||
```bash | ||
npm install angular-async-local-storage@1 | ||
``` | ||
@@ -203,45 +162,2 @@ This module supports [AoT pre-compiling](https://angular.io/guide/aot-compiler). | ||
It also works in tools based on browser engines (like Electron) but not in non-browser tools (like NativeScript, see | ||
[#11](https://github.com/cyrilletuzi/angular-async-local-storage/issues/11)). | ||
### Private mode | ||
Be aware that local storage is limited in browsers when in private / incognito modes. Most browsers will delete the data when the private browsing session ends. | ||
It's not a real issue as local storage is useful for apps, and apps should not be in private mode. | ||
In IE / Edge, `indexedDB` is `null` when in private mode. The lib fallbacks to (synchronous) `localStorage`. | ||
In Firefox, `indexedDB` API is available in code but throwing error on usage. It's a bug in the browser, this lib can't handle it, see | ||
[#26](https://github.com/cyrilletuzi/angular-async-local-storage/issues/26). | ||
## Extensibility | ||
### Add your own storage | ||
Starting with *version 3.1*, you can easily add your own storage : | ||
```typescript | ||
import { AsyncLocalStorageModule, AsyncLocalDatabase } from 'angular-async-local-storage'; | ||
export class MyDatabase extends AsyncLocalDatabase { | ||
/* Implement the methods required by the parent class */ | ||
} | ||
@NgModule({ | ||
provide: [ | ||
AsyncLocalStorageModule, | ||
{ provide: AsyncLocalDatabase, useClass: MyDatabase } | ||
] | ||
}) | ||
export class AppModule {} | ||
``` | ||
Be sure to be compatible with Universal by checking the current platform before using any browser specific API. | ||
### Extend JSON Validator | ||
You can also extend the JSON validator, but if you do so, please contribute so everyone can enjoy. | ||
## Changelog | ||
@@ -248,0 +164,0 @@ |
@@ -1,6 +0,4 @@ | ||
import { IndexedDBDatabase } from './service/databases/indexeddb-database'; | ||
import { LocalStorageDatabase } from './service/databases/localstorage-database'; | ||
import { MockLocalDatabase } from './service/databases/mock-local-database'; | ||
export declare function databaseFactory(platformId: Object): IndexedDBDatabase | LocalStorageDatabase | MockLocalDatabase; | ||
import { AsyncLocalStorage } from './service/lib.service'; | ||
export declare function asyncLocalStorageFactory(platformId: Object): AsyncLocalStorage; | ||
export declare class AsyncLocalStorageModule { | ||
} |
import { Observable } from 'rxjs/Observable'; | ||
import { ReplaySubject } from 'rxjs/ReplaySubject'; | ||
import 'rxjs/add/operator/map'; | ||
import 'rxjs/add/operator/mergeMap'; | ||
import 'rxjs/add/operator/pluck'; | ||
import 'rxjs/add/operator/first'; | ||
import 'rxjs/add/observable/fromEvent'; | ||
import 'rxjs/add/observable/merge'; | ||
import 'rxjs/add/observable/throw'; | ||
import 'rxjs/add/observable/of'; | ||
import { AsyncLocalDatabase } from './async-local-database'; | ||
@@ -4,0 +12,0 @@ export declare class IndexedDBDatabase extends AsyncLocalDatabase { |
import { Observable } from 'rxjs/Observable'; | ||
import 'rxjs/add/observable/of'; | ||
import 'rxjs/add/observable/throw'; | ||
import { AsyncLocalDatabase } from './async-local-database'; | ||
@@ -3,0 +5,0 @@ export declare class LocalStorageDatabase extends AsyncLocalDatabase { |
import { Observable } from 'rxjs/Observable'; | ||
import 'rxjs/add/observable/of'; | ||
import { AsyncLocalDatabase } from './async-local-database'; | ||
@@ -3,0 +4,0 @@ export declare class MockLocalDatabase extends AsyncLocalDatabase { |
import { Observable } from 'rxjs/Observable'; | ||
import { AsyncLocalDatabase } from './databases/async-local-database'; | ||
import { JSONSchema } from './validation/json-schema'; | ||
import { JSONValidator } from './validation/json-validator'; | ||
export interface ALSGetItemOptions { | ||
schema?: JSONSchema | null; | ||
} | ||
export declare class AsyncLocalStorage { | ||
protected database: AsyncLocalDatabase; | ||
protected jsonValidator: JSONValidator; | ||
protected readonly getItemOptionsDefault: { | ||
schema: null; | ||
}; | ||
constructor(database: AsyncLocalDatabase, jsonValidator: JSONValidator); | ||
/** | ||
* Injects a local database | ||
*/ | ||
constructor(database: AsyncLocalDatabase); | ||
/** | ||
* Gets an item value in local storage | ||
@@ -20,3 +14,3 @@ * @param key The item's key | ||
*/ | ||
getItem<T = any>(key: string, options?: ALSGetItemOptions): Observable<any>; | ||
getItem<T = any>(key: string): Observable<T | null>; | ||
/** | ||
@@ -23,0 +17,0 @@ * Sets an item in local storage |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2
36
186416
21
1591
165
1