import { IFetchSegmentChanges } from '../../../services/types'; import { ISegmentChangesResponse } from '../../../dtos/types'; import { ISegmentChangesFetcher } from './types'; function greedyFetch(fetchSegmentChanges: IFetchSegmentChanges, since: number, segmentName: string, noCache?: boolean, targetTill?: number): Promise { return fetchSegmentChanges(since, segmentName, noCache, targetTill) .then(resp => resp.json()) .then((json: ISegmentChangesResponse) => { let { since, till } = json; if (since === till) { return [json]; } else { return Promise.all([json, greedyFetch(fetchSegmentChanges, till, segmentName, noCache, targetTill)]).then(flatMe => { return [flatMe[0], ...flatMe[1]]; }); } }); } /** * Factory of SegmentChanges fetcher. * SegmentChanges fetcher is a wrapper around `segmentChanges` API service that parses the response and handle errors and retries. */ export function segmentChangesFetcherFactory(fetchSegmentChanges: IFetchSegmentChanges): ISegmentChangesFetcher { return function segmentChangesFetcher( since: number, segmentName: string, noCache?: boolean, till?: number, // Optional decorator for `fetchSegmentChanges` promise, such as timeout or time tracker decorator?: (promise: Promise) => Promise ): Promise { let segmentsPromise = greedyFetch(fetchSegmentChanges, since, segmentName, noCache, till); if (decorator) segmentsPromise = decorator(segmentsPromise); return segmentsPromise; }; }