UNPKG

anrom-jive-app-tools

Version:
122 lines (99 loc) 4.2 kB
import { promiseRestBatch } from '../fetchPromise' //todo: so far works with OSAPI batch (not REST) and doesn't load more than required initially (no // full support of "load more") export default class PostSortLoader { constructor (createSignatureRequest, createContentItemRequest, sortingFunction, options) { const optionsDefaults = { // how many items of final sorted content we want to load per each "loadNext" targetCount: 10, //how many batched pages of signature requests to perform batchNumber: 5, // jive batch can take no more than 25 requests per batch. 25 is a default, but we're // putting it here explicitly. // In many cases it's better to ask for signatures in smaller chunks - like 10 times per // 100 items makes it 1000 items per page, but we can stop after each thousand and run // shouldBatchContinue to avoid loading too much content batchMaxEntries: 25, // function that runs after each batch page. If it returns false - batching should stop shouldBatchContinue: null, // function to filter out some signatures before fetching of real data starts. For example // we want to disable of loading some IDs filterSignature: sig => sig } this.options = { ...optionsDefaults, ...options } //global flag telling us that we should stop polling. this.endReached = false //main functions from params this.createSignatureRequest = createSignatureRequest this.createContentItemRequest = createContentItemRequest this.sortingFunction = sortingFunction //collection of just IDs and fields by which content is sorted this.contentSignaturesPool = [] } async loadNext (customLoadNumber = false) { // if poll is empty and end is not reached (means this is first calling of loadNext) - // get those signatures! if (!this.contentSignaturesPool.length && !this.endReached) { this.contentSignaturesPool = await this.getSignatures() } // as long as pool has data - slice in targetCount/customLoadNumber and get individual items if (this.contentSignaturesPool.length) { const contentToRequest = this.contentSignaturesPool.splice(0, customLoadNumber || this.options.targetCount) // but if this was the last slice - flag the "endReached" if (!this.contentSignaturesPool.length) { this.endReached = true } const contentsResponse = await promiseRestBatch(contentToRequest, (entry, eI, rI) => { return { key: rI + '.' + eI, request: { method: 'GET', endpoint: this.createContentItemRequest(entry) } } }) //todo: figure out what to do with errors inside this list (now they're just ignored) return { list: contentsResponse .filter(item => !item.error) .map(item => item.data), reason: this.endReached ? 'source ended' : 'reached target count' } } else { return { list: [], reason: 'polling finished' } } } async getSignatures () { const { batchNumber, filterSignature } = this.options const batchArray = [] for (let i = 0; i < batchNumber; i++) batchArray.push(i) const response = await promiseRestBatch(batchArray, (batchPageIndex, entryIndex, requestIndex) => { return { key: requestIndex + '.' + entryIndex, request: { method: 'GET', endpoint: this.createSignatureRequest(batchPageIndex) } } }, { maxEntries: this.options.batchMaxEntries, shouldBatchContinue: this.options.shouldBatchContinue }) //todo: figure out what to do with errors inside this list (now they're just ignored) const signatures = response .filter(chunk => chunk.status === 200) .map(chunk => chunk.data.list) .reduce((accum, current) => accum.concat(current), []) .filter(sig => filterSignature(sig)) const sortedSignatures = signatures.sort(this.sortingFunction) console.log('response', response) console.log('sortedSignatures', sortedSignatures) return sortedSignatures } }