1
- import { catchError , take } from 'rxjs/operators'
1
+ import { catchError , take , tap } from 'rxjs/operators'
2
2
import { AngularFireDatabase } from 'angularfire2/database'
3
3
import { Inject , Injectable , Optional } from '@angular/core'
4
4
import { HttpClient , HttpParams } from '@angular/common/http'
5
- import { FIREBASE_USER_AUTH_TOKEN } from './server.firebase.module'
5
+ import {
6
+ FIREBASE_USER_AUTH_TOKEN ,
7
+ LRU_CACHE ,
8
+ LruCache
9
+ } from './server.firebase.module'
6
10
import { Observable , of } from 'rxjs'
7
11
import { IUniversalRtdbService } from './rtdb.interface'
12
+ import { createHash } from 'crypto'
13
+
14
+ function sha256 ( data : string ) {
15
+ return createHash ( 'sha256' )
16
+ . update ( data )
17
+ . digest ( 'base64' )
18
+ }
19
+
20
+ function constructFbUrl ( db : AngularFireDatabase , path : string ) {
21
+ const query = db . database . ref ( path )
22
+ return `${ query . toString ( ) } .json`
23
+ }
24
+
25
+ function getFullUrl ( base : string , params : HttpParams ) {
26
+ const stringifiedParams = params . toString ( )
27
+ return stringifiedParams ? `${ base } ?${ params . toString ( ) } ` : base
28
+ }
29
+
30
+ function getParams ( fromObject = { } ) {
31
+ return new HttpParams ( {
32
+ fromObject
33
+ } )
34
+ }
35
+
36
+ function mapUndefined ( err : any ) {
37
+ return of ( undefined )
38
+ }
39
+
40
+ function attempToCacheInLru ( key : string , lru ?: LruCache ) {
41
+ return function ( response ?: any ) {
42
+ lru && lru . set ( sha256 ( key ) , response )
43
+ }
44
+ }
8
45
9
46
// tslint:disable:no-this
10
47
// tslint:disable-next-line:no-class
@@ -15,26 +52,25 @@ export class ServerUniversalRtDbService implements IUniversalRtdbService {
15
52
private afdb : AngularFireDatabase ,
16
53
@Optional ( )
17
54
@Inject ( FIREBASE_USER_AUTH_TOKEN )
18
- private authToken ?: string
55
+ private authToken ?: string ,
56
+ @Optional ( )
57
+ @Inject ( LRU_CACHE )
58
+ private lru ?: LruCache
19
59
) { }
20
60
21
61
universalObject < T > ( path : string ) : Observable < T | undefined > {
22
- const query = this . afdb . database . ref ( path )
23
- const url = `${ query . toString ( ) } .json`
62
+ const url = constructFbUrl ( this . afdb , path )
63
+ const params = getParams ( { auth : this . authToken } )
64
+ const cacheKey = getFullUrl ( url , params )
65
+
24
66
const baseObs = this . authToken
25
- ? this . http . get < T > ( url , {
26
- params : new HttpParams ( {
27
- fromObject : {
28
- auth : this . authToken
29
- }
30
- } )
31
- } )
67
+ ? this . http . get < T > ( url , { params } )
32
68
: this . http . get < T > ( url )
69
+
33
70
return baseObs . pipe (
34
71
take ( 1 ) ,
35
- catchError ( err => {
36
- return of ( undefined )
37
- } )
72
+ tap ( attempToCacheInLru ( cacheKey , this . lru ) ) ,
73
+ catchError ( mapUndefined )
38
74
)
39
75
}
40
76
}
0 commit comments