Advertisement
Guest User

Untitled

a guest
Apr 25th, 2015
218
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.92 KB | None | 0 0
  1. 'use strict';
  2.  
  3. var { union, find, without, clone } = require('underscore'),
  4. invariant = require('react/lib/invariant');
  5.  
  6. class PaginatedList {
  7. constructor(ids) {
  8. this._ids = ids || [];
  9. this._pageCount = 0;
  10. this._nextPageUrl = null;
  11. this._isExpectingPage = false;
  12. this._isInvalidated = false;
  13. }
  14.  
  15. getIds() {
  16. return this._ids;
  17. }
  18.  
  19. getPageCount() {
  20. return this._pageCount;
  21. }
  22.  
  23. isExpectingPage() {
  24. return this._isExpectingPage;
  25. }
  26.  
  27. getNextPageUrl() {
  28. return this._nextPageUrl;
  29. }
  30.  
  31. isLastPage() {
  32. return this._nextPageUrl === null;
  33. }
  34.  
  35. isInvalidated() {
  36. return this._isInvalidated;
  37. }
  38.  
  39. find(predicate) {
  40. return find(this._ids, predicate);
  41. }
  42.  
  43. prepend(id) {
  44. this._ids = union([id], this._ids);
  45. }
  46.  
  47. remove(id) {
  48. this._ids = without(this._ids, id);
  49. }
  50.  
  51. contains(id) {
  52. return this._ids.indexOf(id) !== -1;
  53. }
  54.  
  55. invalidate() {
  56. // Empty is as good as invalidated
  57. if (this._pageCount === 0) {
  58. return;
  59. }
  60.  
  61. // TODO: We'd like to support invalidating in-flight but in order to do that
  62. // `receivePage` needs to be sure whether specific response is next or invalidated page
  63. // and the whole chunk of consuming code will have to be refactored. Leave it for now.
  64.  
  65. if (this._isExpectingPage) {
  66. console.warn('Cannot invalidate while fetching page. Invalidation ignored.');
  67. return;
  68. }
  69.  
  70. this._isInvalidated = true;
  71. }
  72.  
  73. expectPage() {
  74. invariant(!this._isExpectingPage, 'Cannot call expectPage twice without prior cancelPage or receivePage call.');
  75. this._isExpectingPage = true;
  76. }
  77.  
  78. cancelPage() {
  79. invariant(this._isExpectingPage, 'Cannot call cancelPage without prior expectPage call.');
  80. this._isExpectingPage = false;
  81. this._isInvalidated = false;
  82. }
  83.  
  84. receivePage(newIds, nextPageUrl) {
  85. invariant(this._isExpectingPage, 'Cannot call receivePage without prior expectPage call.');
  86. nextPageUrl = nextPageUrl || null;
  87.  
  88. if (this._isInvalidated) {
  89. this.receiveInvalidatedFirstPage(newIds, nextPageUrl);
  90. } else {
  91. this.receiveNextPage(newIds, nextPageUrl);
  92. }
  93.  
  94. this._isExpectingPage = false;
  95. this._isInvalidated = false;
  96. }
  97.  
  98. receiveNextPage(newIds, nextPageUrl) {
  99. this._ids = union(this._ids, newIds);
  100. this._pageCount++;
  101. this._nextPageUrl = nextPageUrl;
  102. }
  103.  
  104. receiveInvalidatedFirstPage(firstPageIds, nextPageUrl) {
  105. var isCommonId = id => this._ids.indexOf(id) > -1,
  106. firstPageIdsBackwards = clone(firstPageIds).reverse(),
  107. lastCommonId = find(firstPageIdsBackwards, isCommonId),
  108. lastCommonIdIndex = this._ids.indexOf(lastCommonId);
  109.  
  110. // Only attempt to merge if there is a common item
  111. if (lastCommonIdIndex > -1) {
  112. this._ids = union(firstPageIds, this._ids.slice(lastCommonIdIndex + 1));
  113. } else {
  114. this._ids = firstPageIds;
  115. this._pageCount = 1;
  116. this._nextPageUrl = nextPageUrl;
  117. }
  118. }
  119. }
  120.  
  121. module.exports = PaginatedList;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement