Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 'use strict';
- var { union, find, without, clone } = require('underscore'),
- invariant = require('react/lib/invariant');
- class PaginatedList {
- constructor(ids) {
- this._ids = ids || [];
- this._pageCount = 0;
- this._nextPageUrl = null;
- this._isExpectingPage = false;
- this._isInvalidated = false;
- }
- getIds() {
- return this._ids;
- }
- getPageCount() {
- return this._pageCount;
- }
- isExpectingPage() {
- return this._isExpectingPage;
- }
- getNextPageUrl() {
- return this._nextPageUrl;
- }
- isLastPage() {
- return this._nextPageUrl === null;
- }
- isInvalidated() {
- return this._isInvalidated;
- }
- find(predicate) {
- return find(this._ids, predicate);
- }
- prepend(id) {
- this._ids = union([id], this._ids);
- }
- remove(id) {
- this._ids = without(this._ids, id);
- }
- contains(id) {
- return this._ids.indexOf(id) !== -1;
- }
- invalidate() {
- // Empty is as good as invalidated
- if (this._pageCount === 0) {
- return;
- }
- // TODO: We'd like to support invalidating in-flight but in order to do that
- // `receivePage` needs to be sure whether specific response is next or invalidated page
- // and the whole chunk of consuming code will have to be refactored. Leave it for now.
- if (this._isExpectingPage) {
- console.warn('Cannot invalidate while fetching page. Invalidation ignored.');
- return;
- }
- this._isInvalidated = true;
- }
- expectPage() {
- invariant(!this._isExpectingPage, 'Cannot call expectPage twice without prior cancelPage or receivePage call.');
- this._isExpectingPage = true;
- }
- cancelPage() {
- invariant(this._isExpectingPage, 'Cannot call cancelPage without prior expectPage call.');
- this._isExpectingPage = false;
- this._isInvalidated = false;
- }
- receivePage(newIds, nextPageUrl) {
- invariant(this._isExpectingPage, 'Cannot call receivePage without prior expectPage call.');
- nextPageUrl = nextPageUrl || null;
- if (this._isInvalidated) {
- this.receiveInvalidatedFirstPage(newIds, nextPageUrl);
- } else {
- this.receiveNextPage(newIds, nextPageUrl);
- }
- this._isExpectingPage = false;
- this._isInvalidated = false;
- }
- receiveNextPage(newIds, nextPageUrl) {
- this._ids = union(this._ids, newIds);
- this._pageCount++;
- this._nextPageUrl = nextPageUrl;
- }
- receiveInvalidatedFirstPage(firstPageIds, nextPageUrl) {
- var isCommonId = id => this._ids.indexOf(id) > -1,
- firstPageIdsBackwards = clone(firstPageIds).reverse(),
- lastCommonId = find(firstPageIdsBackwards, isCommonId),
- lastCommonIdIndex = this._ids.indexOf(lastCommonId);
- // Only attempt to merge if there is a common item
- if (lastCommonIdIndex > -1) {
- this._ids = union(firstPageIds, this._ids.slice(lastCommonIdIndex + 1));
- } else {
- this._ids = firstPageIds;
- this._pageCount = 1;
- this._nextPageUrl = nextPageUrl;
- }
- }
- }
- module.exports = PaginatedList;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement