ChainedMap.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. const merge = require('deepmerge');
  2. const Chainable = require('./Chainable');
  3. module.exports = class extends Chainable {
  4. constructor(parent) {
  5. super(parent);
  6. this.store = new Map();
  7. }
  8. extend(methods) {
  9. this.shorthands = methods;
  10. methods.forEach((method) => {
  11. this[method] = (value) => this.set(method, value);
  12. });
  13. return this;
  14. }
  15. clear() {
  16. this.store.clear();
  17. return this;
  18. }
  19. delete(key) {
  20. this.store.delete(key);
  21. return this;
  22. }
  23. order() {
  24. const entries = [...this.store].reduce((acc, [key, value]) => {
  25. acc[key] = value;
  26. return acc;
  27. }, {});
  28. const names = Object.keys(entries);
  29. const order = [...names];
  30. names.forEach((name) => {
  31. if (!entries[name]) {
  32. return;
  33. }
  34. const { __before, __after } = entries[name];
  35. if (__before && order.includes(__before)) {
  36. order.splice(order.indexOf(name), 1);
  37. order.splice(order.indexOf(__before), 0, name);
  38. } else if (__after && order.includes(__after)) {
  39. order.splice(order.indexOf(name), 1);
  40. order.splice(order.indexOf(__after) + 1, 0, name);
  41. }
  42. });
  43. return { entries, order };
  44. }
  45. entries() {
  46. const { entries, order } = this.order();
  47. if (order.length) {
  48. return entries;
  49. }
  50. return undefined;
  51. }
  52. values() {
  53. const { entries, order } = this.order();
  54. return order.map((name) => entries[name]);
  55. }
  56. get(key) {
  57. return this.store.get(key);
  58. }
  59. getOrCompute(key, fn) {
  60. if (!this.has(key)) {
  61. this.set(key, fn());
  62. }
  63. return this.get(key);
  64. }
  65. has(key) {
  66. return this.store.has(key);
  67. }
  68. set(key, value) {
  69. this.store.set(key, value);
  70. return this;
  71. }
  72. merge(obj, omit = []) {
  73. Object.keys(obj).forEach((key) => {
  74. if (omit.includes(key)) {
  75. return;
  76. }
  77. const value = obj[key];
  78. if (
  79. (!Array.isArray(value) && typeof value !== 'object') ||
  80. value === null ||
  81. !this.has(key)
  82. ) {
  83. this.set(key, value);
  84. } else {
  85. this.set(key, merge(this.get(key), value));
  86. }
  87. });
  88. return this;
  89. }
  90. clean(obj) {
  91. return Object.keys(obj).reduce((acc, key) => {
  92. const value = obj[key];
  93. if (value === undefined) {
  94. return acc;
  95. }
  96. if (Array.isArray(value) && !value.length) {
  97. return acc;
  98. }
  99. if (
  100. Object.prototype.toString.call(value) === '[object Object]' &&
  101. !Object.keys(value).length
  102. ) {
  103. return acc;
  104. }
  105. acc[key] = value;
  106. return acc;
  107. }, {});
  108. }
  109. when(
  110. condition,
  111. whenTruthy = Function.prototype,
  112. whenFalsy = Function.prototype,
  113. ) {
  114. if (condition) {
  115. whenTruthy(this);
  116. } else {
  117. whenFalsy(this);
  118. }
  119. return this;
  120. }
  121. };