No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

hace 3 años
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // core keys merging algorithm. If previous render's keys are [a, b], and the
  2. // next render's [c, b, d], what's the final merged keys and ordering?
  3. // - c and a must both be before b
  4. // - b before d
  5. // - ordering between a and c ambiguous
  6. // this reduces to merging two partially ordered lists (e.g. lists where not
  7. // every item has a definite ordering, like comparing a and c above). For the
  8. // ambiguous ordering we deterministically choose to place the next render's
  9. // item after the previous'; so c after a
  10. // this is called a topological sorting. Except the existing algorithms don't
  11. // work well with js bc of the amount of allocation, and isn't optimized for our
  12. // current use-case bc the runtime is linear in terms of edges (see wiki for
  13. // meaning), which is huge when two lists have many common elements
  14. 'use strict';
  15. exports.__esModule = true;
  16. exports['default'] = mergeDiff;
  17. function mergeDiff(prev, next, onRemove) {
  18. // bookkeeping for easier access of a key's index below. This is 2 allocations +
  19. // potentially triggering chrome hash map mode for objs (so it might be faster
  20. var prevKeyIndex = {};
  21. for (var i = 0; i < prev.length; i++) {
  22. prevKeyIndex[prev[i].key] = i;
  23. }
  24. var nextKeyIndex = {};
  25. for (var i = 0; i < next.length; i++) {
  26. nextKeyIndex[next[i].key] = i;
  27. }
  28. // first, an overly elaborate way of merging prev and next, eliminating
  29. // duplicates (in terms of keys). If there's dupe, keep the item in next).
  30. // This way of writing it saves allocations
  31. var ret = [];
  32. for (var i = 0; i < next.length; i++) {
  33. ret[i] = next[i];
  34. }
  35. for (var i = 0; i < prev.length; i++) {
  36. if (!Object.prototype.hasOwnProperty.call(nextKeyIndex, prev[i].key)) {
  37. // this is called my TM's `mergeAndSync`, which calls willLeave. We don't
  38. // merge in keys that the user desires to kill
  39. var fill = onRemove(i, prev[i]);
  40. if (fill != null) {
  41. ret.push(fill);
  42. }
  43. }
  44. }
  45. // now all the items all present. Core sorting logic to have the right order
  46. return ret.sort(function (a, b) {
  47. var nextOrderA = nextKeyIndex[a.key];
  48. var nextOrderB = nextKeyIndex[b.key];
  49. var prevOrderA = prevKeyIndex[a.key];
  50. var prevOrderB = prevKeyIndex[b.key];
  51. if (nextOrderA != null && nextOrderB != null) {
  52. // both keys in next
  53. return nextKeyIndex[a.key] - nextKeyIndex[b.key];
  54. } else if (prevOrderA != null && prevOrderB != null) {
  55. // both keys in prev
  56. return prevKeyIndex[a.key] - prevKeyIndex[b.key];
  57. } else if (nextOrderA != null) {
  58. // key a in next, key b in prev
  59. // how to determine the order between a and b? We find a "pivot" (term
  60. // abuse), a key present in both prev and next, that is sandwiched between
  61. // a and b. In the context of our above example, if we're comparing a and
  62. // d, b's (the only) pivot
  63. for (var i = 0; i < next.length; i++) {
  64. var pivot = next[i].key;
  65. if (!Object.prototype.hasOwnProperty.call(prevKeyIndex, pivot)) {
  66. continue;
  67. }
  68. if (nextOrderA < nextKeyIndex[pivot] && prevOrderB > prevKeyIndex[pivot]) {
  69. return -1;
  70. } else if (nextOrderA > nextKeyIndex[pivot] && prevOrderB < prevKeyIndex[pivot]) {
  71. return 1;
  72. }
  73. }
  74. // pluggable. default to: next bigger than prev
  75. return 1;
  76. }
  77. // prevOrderA, nextOrderB
  78. for (var i = 0; i < next.length; i++) {
  79. var pivot = next[i].key;
  80. if (!Object.prototype.hasOwnProperty.call(prevKeyIndex, pivot)) {
  81. continue;
  82. }
  83. if (nextOrderB < nextKeyIndex[pivot] && prevOrderA > prevKeyIndex[pivot]) {
  84. return 1;
  85. } else if (nextOrderB > nextKeyIndex[pivot] && prevOrderA < prevKeyIndex[pivot]) {
  86. return -1;
  87. }
  88. }
  89. // pluggable. default to: next bigger than prev
  90. return -1;
  91. });
  92. }
  93. module.exports = exports['default'];
  94. // to loop through and find a key's index each time), but I no longer care