88 BehaviorSubject ,
99 forkJoin ,
1010 defer ,
11+ combineLatest ,
1112} from "rxjs" ;
1213import * as rxjsop from "rxjs/operators" ;
1314import { EMPTY } from "rxjs" ;
@@ -256,6 +257,10 @@ export class RealSearchService implements SearchService {
256257 return this . appConfig . getConfig ( ) . pipe (
257258 rxjsop . mergeMap ( ( conf ) => {
258259 const empty = this . emptyResult ( ) ;
260+ const hasRecordsRequest = includeData && ! ! url ;
261+ const hasCodeRequest = includeCode && ! ! externalUrl ;
262+ const hasPapersRequest = includePapers && ! ! papersUrl ;
263+ const hasPatentsRequest = includePatents && ! ! patentsUrl ;
259264 const records$ =
260265 includeData && url
261266 ? this . http
@@ -316,11 +321,25 @@ export class RealSearchService implements SearchService {
316321 )
317322 : of ( empty ) ;
318323
319- return forkJoin ( {
320- records : records$ ,
321- external : external$ ,
322- papers : papers$ ,
323- patents : patents$ ,
324+ const primaryKey : "records" | "external" | "patents" | "papers" =
325+ hasRecordsRequest
326+ ? "records"
327+ : hasCodeRequest
328+ ? "external"
329+ : hasPatentsRequest
330+ ? "patents"
331+ : "papers" ;
332+
333+ const wrap = (
334+ key : "records" | "external" | "papers" | "patents" ,
335+ source : Observable < any >
336+ ) => ( key === primaryKey ? source : source . pipe ( rxjsop . startWith ( empty ) ) ) ;
337+
338+ return combineLatest ( {
339+ records : wrap ( "records" , records$ ) ,
340+ external : wrap ( "external" , external$ ) ,
341+ papers : wrap ( "papers" , papers$ ) ,
342+ patents : wrap ( "patents" , patents$ ) ,
324343 } ) . pipe (
325344 rxjsop . map ( ( { records, external, papers, patents } ) =>
326345 this . combineResults ( records , external , patents , papers )
@@ -1287,13 +1306,18 @@ export class RealSearchService implements SearchService {
12871306 }
12881307
12891308 setProductTypes ( state : Partial < ProductTypeState > ) : void {
1309+ const current = this . productTypes . getValue ( ) ;
12901310 const next = this . normalizeProductState ( {
1291- ...this . productTypes . getValue ( ) ,
1311+ ...current ,
12921312 ...state ,
12931313 } ) ;
1314+ if ( _ . isEqual ( current , next ) ) {
1315+ return ;
1316+ }
12941317 this . productTypes . next ( next ) ;
12951318 this . persistProductPref ( next ) ;
12961319 this . resetProgressState ( ) ;
1320+ this . syncProductQueryParams ( ) ;
12971321 }
12981322
12991323 setProductTypeEnabled ( type : ProductTypeKey , enabled : boolean ) : void {
@@ -1305,9 +1329,13 @@ export class RealSearchService implements SearchService {
13051329 ...current ,
13061330 [ type ] : ! ! enabled ,
13071331 } ) ;
1332+ if ( _ . isEqual ( current , next ) ) {
1333+ return ;
1334+ }
13081335 this . productTypes . next ( next ) ;
13091336 this . persistProductPref ( next ) ;
13101337 this . resetProgressState ( ) ;
1338+ this . syncProductQueryParams ( ) ;
13111339 }
13121340
13131341 getActiveProductTypes ( ) : ProductTypeKey [ ] {
@@ -1325,9 +1353,13 @@ export class RealSearchService implements SearchService {
13251353
13261354 setExternalProducts ( enabled : boolean ) : void {
13271355 const normalized = ! ! enabled ;
1356+ if ( this . externalProducts . getValue ( ) === normalized ) {
1357+ return ;
1358+ }
13281359 this . externalProducts . next ( normalized ) ;
13291360 this . persistExternalPref ( normalized ) ;
13301361 this . resetProgressState ( ) ;
1362+ this . syncProductQueryParams ( ) ;
13311363 }
13321364
13331365 watchExternalProducts ( ) : Observable < boolean > {
@@ -1352,6 +1384,41 @@ export class RealSearchService implements SearchService {
13521384 }
13531385 }
13541386
1387+ private syncProductQueryParams ( ) : void {
1388+ const currentUrl = this . router . url || "" ;
1389+ if ( ! currentUrl . startsWith ( "/search" ) ) {
1390+ return ;
1391+ }
1392+ const tree = this . router . parseUrl ( currentUrl ) ;
1393+ const currentParams = tree . queryParams || { } ;
1394+ const activeProducts = this . getActiveProductTypes ( ) ;
1395+ const nextParams : Record < string , any > = { ...currentParams } ;
1396+
1397+ if ( activeProducts . length ) {
1398+ nextParams . products = activeProducts . join ( "," ) ;
1399+ } else {
1400+ delete nextParams . products ;
1401+ }
1402+
1403+ if ( this . externalProducts . getValue ( ) ) {
1404+ nextParams . external = "true" ;
1405+ } else {
1406+ delete nextParams . external ;
1407+ }
1408+
1409+ const normalize = ( value : any ) =>
1410+ typeof value === "undefined" ? "" : String ( value ) ;
1411+ if (
1412+ normalize ( currentParams . products ) === normalize ( nextParams . products ) &&
1413+ normalize ( currentParams . external ) === normalize ( nextParams . external )
1414+ ) {
1415+ return ;
1416+ }
1417+
1418+ tree . queryParams = nextParams ;
1419+ this . router . navigateByUrl ( tree , { replaceUrl : true } ) ;
1420+ }
1421+
13551422 private normalizeProductState (
13561423 state : Partial < ProductTypeState > | null | undefined
13571424 ) : ProductTypeState {
0 commit comments