diff --git a/projects/ngx-pwa/local-storage/src/lib/databases/indexeddb-database.ts b/projects/ngx-pwa/local-storage/src/lib/databases/indexeddb-database.ts index 9383f5de..1b8c2d49 100644 --- a/projects/ngx-pwa/local-storage/src/lib/databases/indexeddb-database.ts +++ b/projects/ngx-pwa/local-storage/src/lib/databases/indexeddb-database.ts @@ -4,7 +4,7 @@ import { map, mergeMap, first, tap, filter } from 'rxjs/operators'; import { LocalDatabase } from './local-database'; import { LocalStorageDatabase } from './localstorage-database'; -import { LOCAL_STORAGE_PREFIX } from '../tokens'; +import { PREFIX, INDEXEDDB_NAME, DEFAULT_INDEXEDDB_NAME, INDEXEDDB_STORE_NAME, DEFAULT_INDEXEDDB_STORE_NAME } from '../tokens'; @Injectable({ providedIn: 'root' @@ -14,15 +14,11 @@ export class IndexedDBDatabase implements LocalDatabase { /** * IndexedDB database name for local storage */ - protected dbName = 'ngStorage'; + protected dbName: string; /** * IndexedDB object store name for local storage */ - protected readonly objectStoreName = 'localStorage'; - /** - * IndexedDB key path name for local storage (where an item's key will be stored) - */ - protected readonly keyPath = 'key'; + protected objectStoreName: string; /** * IndexedDB data path name for local storage (where items' value will be stored) */ @@ -67,13 +63,15 @@ export class IndexedDBDatabase implements LocalDatabase { /** * Connects to IndexedDB */ - constructor(@Optional() @Inject(LOCAL_STORAGE_PREFIX) protected prefix: string | null = null) { + constructor( + @Optional() @Inject(PREFIX) prefix: string | null = null, + @Optional() @Inject(INDEXEDDB_NAME) dbName = DEFAULT_INDEXEDDB_NAME, + @Optional() @Inject(INDEXEDDB_STORE_NAME) storeName = DEFAULT_INDEXEDDB_STORE_NAME, + ) { - if (prefix) { + this.dbName = prefix ? `${prefix}_${dbName}` : dbName; - this.dbName = `${prefix}_${this.dbName}`; - - } + this.objectStoreName = storeName; /* Creating the RxJS ReplaySubject */ this.database = new ReplaySubject(); diff --git a/projects/ngx-pwa/local-storage/src/lib/databases/local-database.ts b/projects/ngx-pwa/local-storage/src/lib/databases/local-database.ts index fe1a4c8a..d68e9068 100644 --- a/projects/ngx-pwa/local-storage/src/lib/databases/local-database.ts +++ b/projects/ngx-pwa/local-storage/src/lib/databases/local-database.ts @@ -5,7 +5,7 @@ import { Observable } from 'rxjs'; import { IndexedDBDatabase } from './indexeddb-database'; import { LocalStorageDatabase } from './localstorage-database'; import { MockLocalDatabase } from './mock-local-database'; -import { LOCAL_STORAGE_PREFIX } from '../tokens'; +import { PREFIX } from '../tokens'; export function localDatabaseFactory(platformId: Object, prefix: string | null) { @@ -33,7 +33,7 @@ export function localDatabaseFactory(platformId: Object, prefix: string | null) useFactory: localDatabaseFactory, deps: [ PLATFORM_ID, - [new Optional(), LOCAL_STORAGE_PREFIX] + [new Optional(), PREFIX] ] }) export abstract class LocalDatabase { diff --git a/projects/ngx-pwa/local-storage/src/lib/databases/localstorage-database.ts b/projects/ngx-pwa/local-storage/src/lib/databases/localstorage-database.ts index 8462959b..49e6fb70 100644 --- a/projects/ngx-pwa/local-storage/src/lib/databases/localstorage-database.ts +++ b/projects/ngx-pwa/local-storage/src/lib/databases/localstorage-database.ts @@ -2,7 +2,7 @@ import { Injectable, Optional, Inject } from '@angular/core'; import { Observable, of, throwError } from 'rxjs'; import { LocalDatabase } from './local-database'; -import { LOCAL_STORAGE_PREFIX } from '../tokens'; +import { PREFIX } from '../tokens'; @Injectable({ providedIn: 'root' @@ -16,7 +16,7 @@ export class LocalStorageDatabase implements LocalDatabase { return of(localStorage.length); } - constructor(@Optional() @Inject(LOCAL_STORAGE_PREFIX) protected userPrefix: string | null = null) { + constructor(@Optional() @Inject(PREFIX) userPrefix: string | null = null) { if (userPrefix) { this.prefix = `${userPrefix}_`; diff --git a/projects/ngx-pwa/local-storage/src/lib/lib.service.spec.ts b/projects/ngx-pwa/local-storage/src/lib/lib.service.spec.ts index d3465378..6473a226 100755 --- a/projects/ngx-pwa/local-storage/src/lib/lib.service.spec.ts +++ b/projects/ngx-pwa/local-storage/src/lib/lib.service.spec.ts @@ -1035,6 +1035,23 @@ describe('LocalStorage with IndexedDB and a prefix', () => { }); + it('should have the wanted prefix with custom database and object store names', () => { + + const prefix = 'myapp'; + const dbName = 'customDb'; + + class IndexedDBDatabasePrefix extends IndexedDBDatabase { + getDbBame() { + return this.dbName; + } + } + + const indexedDBService = new IndexedDBDatabasePrefix(prefix, dbName); + + expect(indexedDBService.getDbBame()).toBe(`${prefix}_${dbName}`); + + }); + const localStorageService = new LocalStorage(new IndexedDBDatabase('myapp'), new JSONValidator()); beforeEach((done: DoneFn) => { @@ -1047,6 +1064,20 @@ describe('LocalStorage with IndexedDB and a prefix', () => { }); +describe('LocalStorage with IndexedDB and a custom database and object store names', () => { + + const localStorageService = new LocalStorage(new IndexedDBDatabase(null, 'dBcustom', 'storeCustom'), new JSONValidator()); + + beforeEach((done: DoneFn) => { + localStorageService.clear().subscribe(() => { + done(); + }); + }); + + tests(localStorageService); + +}); + describe('LocalStorage with automatic storage injection', () => { it('should store and get the same value', (done: DoneFn) => { diff --git a/projects/ngx-pwa/local-storage/src/lib/tokens.ts b/projects/ngx-pwa/local-storage/src/lib/tokens.ts index 01d98c5d..5aef9e61 100644 --- a/projects/ngx-pwa/local-storage/src/lib/tokens.ts +++ b/projects/ngx-pwa/local-storage/src/lib/tokens.ts @@ -1,15 +1,82 @@ import { InjectionToken, Provider } from '@angular/core'; -export const LOCAL_STORAGE_PREFIX = new InjectionToken('localStoragePrefix', { providedIn: 'root', factory: () => '' }); +/** + * Internal. Use the `localStorageProviders()` helper function to provide options. + */ +export const PREFIX = new InjectionToken('localStoragePrefix', { + providedIn: 'root', + factory: () => '' +}); + +/** + * @deprecated Use the `localStorageProviders()` helper function to provide options. + */ +export const LOCAL_STORAGE_PREFIX = PREFIX; + +/** + * Default name used for `indexedDb` database. + * *Use only for interoperability with other APIs.* + */ +export const DEFAULT_INDEXEDDB_NAME = 'ngStorage'; + +/** + * Internal. Use the `localStorageProviders()` helper function to provide options. + */ +export const INDEXEDDB_NAME = new InjectionToken('localStorageIndexedDbName', { + providedIn: 'root', + factory: () => DEFAULT_INDEXEDDB_NAME +}); + +/** + * Default name used for `indexedDb` object store. + * *Use only for interoperability with other APIs.* + */ +export const DEFAULT_INDEXEDDB_STORE_NAME = 'localStorage'; + +/** + * Internal. Use the `localStorageProviders()` helper function to provide options. + */ +export const INDEXEDDB_STORE_NAME = new InjectionToken('localStorageIndexedDbStoreName', { + providedIn: 'root', + factory: () => DEFAULT_INDEXEDDB_STORE_NAME +}); export interface LocalStorageProvidersConfig { - /** Optional prefix to avoid collision in multiple apps on same subdomain */ + /** + * Optional prefix to avoid collision when there are *multiple apps on the same subdomain* + * (makes no sense in other scenarios). **Avoid special characters.** + * **WARNING: do not change this option in an app already deployed in production, as previously stored data would be lost.** + */ prefix?: string; + + /** + * Allows to change the name used for `indexedDb` database. **Avoid special characters.** + * *Use only for interoperability with other APIs or to avoid collision with other libs.* + * **WARNING: do not change this option in an app already deployed in production, as previously stored data would be lost.** + */ + indexedDbName?: string; + + /** + * Allows to change the name used for `indexedDb` object store. **Avoid special characters.** + * *Use only for interoperability with other APIs or to avoid collision with other libs.* + * **WARNING: do not change this option in an app already deployed in production, as previously stored data would be lost.** + */ + indexedDbStoreName?: string; + } +/** + * Helper function to provide options. **Must be used at initialization, ie. in `AppModule`.** + * @param config Options. + * @returns A list of providers for the lib options. + */ export function localStorageProviders(config: LocalStorageProvidersConfig): Provider[] { + return [ - config.prefix ? { provide: LOCAL_STORAGE_PREFIX, useValue: config.prefix } : [] + config.prefix ? { provide: PREFIX, useValue: config.prefix } : [], + config.indexedDbName ? { provide: INDEXEDDB_NAME, useValue: config.indexedDbName } : [], + config.indexedDbStoreName ? { provide: INDEXEDDB_STORE_NAME, useValue: config.indexedDbStoreName } : [], ]; + } diff --git a/projects/ngx-pwa/local-storage/src/public_api.ts b/projects/ngx-pwa/local-storage/src/public_api.ts index a00ff6c3..c86a63ce 100644 --- a/projects/ngx-pwa/local-storage/src/public_api.ts +++ b/projects/ngx-pwa/local-storage/src/public_api.ts @@ -12,4 +12,7 @@ export { LocalStorageDatabase } from './lib/databases/localstorage-database'; export { MockLocalDatabase } from './lib/databases/mock-local-database'; export { JSONValidator } from './lib/validation/json-validator'; export { LSGetItemOptions, LocalStorage } from './lib/lib.service'; -export { localStorageProviders, LocalStorageProvidersConfig, LOCAL_STORAGE_PREFIX } from './lib/tokens'; +export { + localStorageProviders, LocalStorageProvidersConfig, LOCAL_STORAGE_PREFIX, PREFIX, + DEFAULT_INDEXEDDB_NAME, INDEXEDDB_NAME, DEFAULT_INDEXEDDB_STORE_NAME, INDEXEDDB_STORE_NAME +} from './lib/tokens';