Adding ServerTransferStateModule for AU with custom http interceptor for cache transfer.
This commit is contained in:
		
							parent
							
								
									5248fadcea
								
							
						
					
					
						commit
						d0da875e69
					
				@ -1,6 +1,6 @@
 | 
			
		||||
import { BrowserModule } from '@angular/platform-browser';
 | 
			
		||||
import { BrowserModule, BrowserTransferStateModule } from '@angular/platform-browser';
 | 
			
		||||
import { NgModule } from '@angular/core';
 | 
			
		||||
import { HttpClientModule } from '@angular/common/http';
 | 
			
		||||
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
 | 
			
		||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 | 
			
		||||
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
 | 
			
		||||
 | 
			
		||||
@ -48,6 +48,7 @@ import { faAngleDoubleDown, faAngleDoubleUp, faAngleDown, faAngleUp, faBolt, faC
 | 
			
		||||
import { ApiDocsComponent } from './components/api-docs/api-docs.component';
 | 
			
		||||
import { TermsOfServiceComponent } from './components/terms-of-service/terms-of-service.component';
 | 
			
		||||
import { StorageService } from './services/storage.service';
 | 
			
		||||
import { HttpCacheInterceptor } from './services/http-cache.interceptor';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
  declarations: [
 | 
			
		||||
@ -85,6 +86,7 @@ import { StorageService } from './services/storage.service';
 | 
			
		||||
  ],
 | 
			
		||||
  imports: [
 | 
			
		||||
    BrowserModule.withServerTransition({ appId: 'serverApp' }),
 | 
			
		||||
    BrowserTransferStateModule,
 | 
			
		||||
    AppRoutingModule,
 | 
			
		||||
    HttpClientModule,
 | 
			
		||||
    BrowserAnimationsModule,
 | 
			
		||||
@ -100,6 +102,7 @@ import { StorageService } from './services/storage.service';
 | 
			
		||||
    AudioService,
 | 
			
		||||
    SeoService,
 | 
			
		||||
    StorageService,
 | 
			
		||||
    { provide: HTTP_INTERCEPTORS, useClass: HttpCacheInterceptor, multi: true }
 | 
			
		||||
  ],
 | 
			
		||||
  bootstrap: [AppComponent]
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,19 @@
 | 
			
		||||
import { HTTP_INTERCEPTORS } from '@angular/common/http';
 | 
			
		||||
import { NgModule } from '@angular/core';
 | 
			
		||||
import { ServerModule } from '@angular/platform-server';
 | 
			
		||||
import { ServerModule, ServerTransferStateModule } from '@angular/platform-server';
 | 
			
		||||
 | 
			
		||||
import { AppModule } from './app.module';
 | 
			
		||||
import { AppComponent } from './components/app/app.component';
 | 
			
		||||
import { HttpCacheInterceptor } from './services/http-cache.interceptor';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
  imports: [
 | 
			
		||||
    AppModule,
 | 
			
		||||
    ServerModule,
 | 
			
		||||
    ServerTransferStateModule,
 | 
			
		||||
  ],
 | 
			
		||||
  providers: [
 | 
			
		||||
    { provide: HTTP_INTERCEPTORS, useClass: HttpCacheInterceptor, multi: true }
 | 
			
		||||
  ],
 | 
			
		||||
  bootstrap: [AppComponent],
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										42
									
								
								frontend/src/app/services/http-cache.interceptor.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								frontend/src/app/services/http-cache.interceptor.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
import { Inject, Injectable, PLATFORM_ID } from '@angular/core';
 | 
			
		||||
import { HttpInterceptor, HttpEvent, HttpRequest, HttpHandler, HttpResponse } from '@angular/common/http';
 | 
			
		||||
import { Observable, of } from 'rxjs';
 | 
			
		||||
import { tap } from 'rxjs/operators';
 | 
			
		||||
import { TransferState, makeStateKey } from '@angular/platform-browser';
 | 
			
		||||
import { isPlatformBrowser } from '@angular/common';
 | 
			
		||||
 | 
			
		||||
@Injectable()
 | 
			
		||||
export class HttpCacheInterceptor implements HttpInterceptor {
 | 
			
		||||
  isBrowser: boolean = isPlatformBrowser(this.platformId);
 | 
			
		||||
 | 
			
		||||
  constructor(
 | 
			
		||||
    private transferState: TransferState,
 | 
			
		||||
    @Inject(PLATFORM_ID) private platformId: any,
 | 
			
		||||
  ) { }
 | 
			
		||||
 | 
			
		||||
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
 | 
			
		||||
    if (this.isBrowser && request.method === 'GET') {
 | 
			
		||||
 | 
			
		||||
      const cachedResponse = this.transferState.get(makeStateKey(request.url), null);
 | 
			
		||||
      if (cachedResponse) {
 | 
			
		||||
        const modifiedResponse = new HttpResponse<any>({
 | 
			
		||||
          headers: cachedResponse.headers,
 | 
			
		||||
          body: cachedResponse.body,
 | 
			
		||||
          status: cachedResponse.status,
 | 
			
		||||
          statusText: cachedResponse.statusText,
 | 
			
		||||
          url: cachedResponse.url
 | 
			
		||||
        });
 | 
			
		||||
        this.transferState.remove(makeStateKey(request.url));
 | 
			
		||||
        return of(modifiedResponse);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return next.handle(request)
 | 
			
		||||
      .pipe(tap((event: HttpEvent<any>) => {
 | 
			
		||||
        if (!this.isBrowser && event instanceof HttpResponse) {
 | 
			
		||||
          const keyId = request.url.split('/').slice(3).join('/');
 | 
			
		||||
          this.transferState.set(makeStateKey('/' + keyId), event);
 | 
			
		||||
        }
 | 
			
		||||
      }));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -6,12 +6,14 @@ import { Block, Transaction } from '../interfaces/electrs.interface';
 | 
			
		||||
import { Subscription } from 'rxjs';
 | 
			
		||||
import { ApiService } from './api.service';
 | 
			
		||||
import { take } from 'rxjs/operators';
 | 
			
		||||
 | 
			
		||||
import { TransferState, makeStateKey } from '@angular/platform-browser';
 | 
			
		||||
 | 
			
		||||
const OFFLINE_RETRY_AFTER_MS = 10000;
 | 
			
		||||
const OFFLINE_PING_CHECK_AFTER_MS = 30000;
 | 
			
		||||
const EXPECT_PING_RESPONSE_AFTER_MS = 4000;
 | 
			
		||||
 | 
			
		||||
const initData = makeStateKey('/api/v1/init-data');
 | 
			
		||||
 | 
			
		||||
@Injectable({
 | 
			
		||||
  providedIn: 'root'
 | 
			
		||||
})
 | 
			
		||||
@ -32,6 +34,7 @@ export class WebsocketService {
 | 
			
		||||
  constructor(
 | 
			
		||||
    private stateService: StateService,
 | 
			
		||||
    private apiService: ApiService,
 | 
			
		||||
    private transferState: TransferState,
 | 
			
		||||
  ) {
 | 
			
		||||
    if (!this.stateService.isBrowser) {
 | 
			
		||||
      // @ts-ignore
 | 
			
		||||
@ -40,11 +43,17 @@ export class WebsocketService {
 | 
			
		||||
      this.apiService.getInitData$()
 | 
			
		||||
        .pipe(take(1))
 | 
			
		||||
        .subscribe((response) => this.handleResponse(response));
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
      this.network = this.stateService.network === 'bisq' && !this.stateService.env.BISQ_SEPARATE_BACKEND ? '' : this.stateService.network;
 | 
			
		||||
      this.websocketSubject = webSocket<WebsocketResponse>(this.webSocketUrl.replace('{network}', this.network ? '/' + this.network : ''));
 | 
			
		||||
      this.startSubscription();
 | 
			
		||||
 | 
			
		||||
      const theInitData = this.transferState.get(initData, null);
 | 
			
		||||
      if (theInitData) {
 | 
			
		||||
        this.handleResponse(theInitData.body);
 | 
			
		||||
        this.startSubscription(false, true);
 | 
			
		||||
      } else {
 | 
			
		||||
        this.startSubscription();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.stateService.networkChanged$.subscribe((network) => {
 | 
			
		||||
        if (network === 'bisq' && !this.stateService.env.BISQ_SEPARATE_BACKEND) {
 | 
			
		||||
@ -70,12 +79,14 @@ export class WebsocketService {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  startSubscription(retrying = false) {
 | 
			
		||||
    this.stateService.isLoadingWebSocket$.next(true);
 | 
			
		||||
  startSubscription(retrying = false, hasInitData = false) {
 | 
			
		||||
    if (!hasInitData) {
 | 
			
		||||
      this.stateService.isLoadingWebSocket$.next(true);
 | 
			
		||||
      this.websocketSubject.next({'action': 'init'});
 | 
			
		||||
    }
 | 
			
		||||
    if (retrying) {
 | 
			
		||||
      this.stateService.connectionState$.next(1);
 | 
			
		||||
    }
 | 
			
		||||
    this.websocketSubject.next({'action': 'init'});
 | 
			
		||||
    this.subscription = this.websocketSubject
 | 
			
		||||
      .subscribe((response: WebsocketResponse) => {
 | 
			
		||||
        this.stateService.isLoadingWebSocket$.next(false);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user