import path from 'path'; import { EMPTY, Subject } from 'rxjs'; import { expand, map, reduce, takeUntil } from 'rxjs/operators'; import { RequestPayload, SortingOptions } from '../..'; import { SearchTerm, QueryBuilder } from '../../../query-system'; import { BaseEndpoint, PAGE_SIZE, Pagination } from '../../base'; import { DataPoints } from '../../shared-types'; import PatentConfig from '../config'; import { Patent } from '../models'; export interface RangeArgs extends Pagination { startDate: string; endDate: string; } export interface PatentResponse { patents: Patent[]; count: number; total_patent_count: number; } function buildRangeQueryStringObject(args: RangeArgs): SearchTerm[] { return [ { _eq: { patent_type: 'design' } }, { _gte: { patent_date: args.startDate } }, { _lte: { patent_date: args.endDate } } ]; } export class Range extends BaseEndpoint { protected pageSize: number; private pages: number; private endNotifier = new Subject(); constructor() { super(); this.apiEndpointUrl = path.join(PatentConfig.subsdirectory, PatentConfig.endpoint); } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types between({ args, dataPoints = [], sortBy }: { args: RangeArgs; dataPoints?: DataPoints; sortBy?: SortingOptions; }) { const { pageSize, ...rangeArgs } = args; this.pageSize = pageSize || PAGE_SIZE; this.pages = args.pages || 10; const queryObject = QueryBuilder.build({ and: buildRangeQueryStringObject(args) }); const requestArgs = { args: rangeArgs, dataPoints, queryParamObject: queryObject, sortingOptions: sortBy } as RequestPayload; return this.request(requestArgs, 1).pipe( expand((data, index) => { const { count, total_patent_count } = data; const hasHitMaxUserReqPageCount = this.pageSize * this.pages <= count; const hasHitMaxServerPageCount = count >= total_patent_count; if (hasHitMaxServerPageCount || hasHitMaxUserReqPageCount) { this.completeRequestSequence(); return EMPTY; } const nextPage = index + 1; return this.request(requestArgs, nextPage); }), takeUntil(this.endNotifier), map((data) => [...data.patents]), reduce((acc, data) => { return acc.concat(...data); }) ); } protected override mapper(data: string): PatentResponse { return JSON.parse(data) as PatentResponse; } private completeRequestSequence() { this.endNotifier.next(true); this.endNotifier.complete(); } }