You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

functions.js 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import _ from 'lodash';
  2. /**
  3. * Sets specific properties of a specific state to specific values and prevents
  4. * unnecessary state changes.
  5. *
  6. * @param {Object} target - The state on which the specified properties are to
  7. * be set.
  8. * @param {Object} source - The map of properties to values which are to be set
  9. * on the specified target.
  10. * @returns {Object} The specified target if the values of the specified
  11. * properties equal the specified values; otherwise, a new state constructed
  12. * from the specified target by setting the specified properties to the
  13. * specified values.
  14. */
  15. export function assign(target, source) {
  16. let t = target;
  17. for (const property in source) { // eslint-disable-line guard-for-in
  18. t = set(t, property, source[property], t === target);
  19. }
  20. return t;
  21. }
  22. /**
  23. * Determines whether {@code a} equals {@code b} according to deep comparison
  24. * (which makes sense for Redux and its state definition).
  25. *
  26. * @param {*} a - The value to compare to {@code b}.
  27. * @param {*} b - The value to compare to {@code a}.
  28. * @returns {boolean} True if {@code a} equals {@code b} (according to deep
  29. * comparison); false, otherwise.
  30. */
  31. export function equals(a, b) {
  32. return _.isEqual(a, b);
  33. }
  34. /**
  35. * Sets a specific property of a specific state to a specific value. Prevents
  36. * unnecessary state changes (when the specified <tt>value</tt> is equal to the
  37. * value of the specified <tt>property</tt> of the specified <tt>state</tt>).
  38. *
  39. * @param {Object} state - The (Redux) state from which a new state is to be
  40. * constructed by setting the specified <tt>property</tt> to the specified
  41. * <tt>value</tt>.
  42. * @param {string} property - The property of <tt>state</tt> which is to be
  43. * assigned the specified <tt>value</tt> (in the new state).
  44. * @param {*} value - The value to assign to the specified <tt>property</tt>.
  45. * @returns {Object} The specified <tt>state</tt> if the value of the specified
  46. * <tt>property</tt> equals the specified <tt>value/tt>; otherwise, a new state
  47. * constructed from the specified <tt>state</tt> by setting the specified
  48. * <tt>property</tt> to the specified <tt>value</tt>.
  49. */
  50. export function set(state, property, value) {
  51. return _set(state, property, value, /* copyOnWrite */ true);
  52. }
  53. /* eslint-disable max-params */
  54. /**
  55. * Sets a specific property of a specific state to a specific value. Prevents
  56. * unnecessary state changes (when the specified <tt>value</tt> is equal to the
  57. * value of the specified <tt>property</tt> of the specified <tt>state</tt>).
  58. *
  59. * @param {Object} state - The (Redux) state from which a state is to be
  60. * constructed by setting the specified <tt>property</tt> to the specified
  61. * <tt>value</tt>.
  62. * @param {string} property - The property of <tt>state</tt> which is to be
  63. * assigned the specified <tt>value</tt>.
  64. * @param {*} value - The value to assign to the specified <tt>property</tt>.
  65. * @param {boolean} copyOnWrite - If the specified <tt>state</tt> is to not be
  66. * modified, <tt>true</tt>; otherwise, <tt>false</tt>.
  67. * @returns {Object} The specified <tt>state</tt> if the value of the specified
  68. * <tt>property</tt> equals the specified <tt>value/tt> or <tt>copyOnWrite</tt>
  69. * is truthy; otherwise, a new state constructed from the specified
  70. * <tt>state</tt> by setting the specified <tt>property</tt> to the specified
  71. * <tt>value</tt>.
  72. */
  73. function _set(state, property, value, copyOnWrite) {
  74. // Delete state properties that are to be set to undefined. (It is a matter
  75. // of personal preference, mostly.)
  76. if (typeof value === 'undefined'
  77. && Object.prototype.hasOwnProperty.call(state, property)) {
  78. const newState = copyOnWrite ? { ...state } : state;
  79. if (delete newState[property]) {
  80. return newState;
  81. }
  82. }
  83. if (state[property] !== value) {
  84. if (copyOnWrite) {
  85. return {
  86. ...state,
  87. [property]: value
  88. };
  89. }
  90. state[property] = value;
  91. }
  92. return state;
  93. }
  94. /* eslint-enable max-params */