市场夺宝奇兵
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.

92 lines
2.4 KiB

  1. import { s as serialize } from '../shared/ohash.D__AXeF1.mjs';
  2. export { i as isEqual } from '../shared/ohash.D__AXeF1.mjs';
  3. function diff(obj1, obj2) {
  4. const h1 = _toHashedObject(obj1);
  5. const h2 = _toHashedObject(obj2);
  6. return _diff(h1, h2);
  7. }
  8. function _diff(h1, h2) {
  9. const diffs = [];
  10. const allProps = /* @__PURE__ */ new Set([
  11. ...Object.keys(h1.props || {}),
  12. ...Object.keys(h2.props || {})
  13. ]);
  14. if (h1.props && h2.props) {
  15. for (const prop of allProps) {
  16. const p1 = h1.props[prop];
  17. const p2 = h2.props[prop];
  18. if (p1 && p2) {
  19. diffs.push(..._diff(h1.props?.[prop], h2.props?.[prop]));
  20. } else if (p1 || p2) {
  21. diffs.push(
  22. new DiffEntry((p2 || p1).key, p1 ? "removed" : "added", p2, p1)
  23. );
  24. }
  25. }
  26. }
  27. if (allProps.size === 0 && h1.hash !== h2.hash) {
  28. diffs.push(new DiffEntry((h2 || h1).key, "changed", h2, h1));
  29. }
  30. return diffs;
  31. }
  32. function _toHashedObject(obj, key = "") {
  33. if (obj && typeof obj !== "object") {
  34. return new DiffHashedObject(key, obj, serialize(obj));
  35. }
  36. const props = {};
  37. const hashes = [];
  38. for (const _key in obj) {
  39. props[_key] = _toHashedObject(obj[_key], key ? `${key}.${_key}` : _key);
  40. hashes.push(props[_key].hash);
  41. }
  42. return new DiffHashedObject(key, obj, `{${hashes.join(":")}}`, props);
  43. }
  44. class DiffEntry {
  45. constructor(key, type, newValue, oldValue) {
  46. this.key = key;
  47. this.type = type;
  48. this.newValue = newValue;
  49. this.oldValue = oldValue;
  50. }
  51. toString() {
  52. return this.toJSON();
  53. }
  54. toJSON() {
  55. switch (this.type) {
  56. case "added": {
  57. return `Added \`${this.key}\``;
  58. }
  59. case "removed": {
  60. return `Removed \`${this.key}\``;
  61. }
  62. case "changed": {
  63. return `Changed \`${this.key}\` from \`${this.oldValue?.toString() || "-"}\` to \`${this.newValue.toString()}\``;
  64. }
  65. }
  66. }
  67. }
  68. class DiffHashedObject {
  69. constructor(key, value, hash, props) {
  70. this.key = key;
  71. this.value = value;
  72. this.hash = hash;
  73. this.props = props;
  74. }
  75. toString() {
  76. if (this.props) {
  77. return `{${Object.keys(this.props).join(",")}}`;
  78. } else {
  79. return JSON.stringify(this.value);
  80. }
  81. }
  82. toJSON() {
  83. const k = this.key || ".";
  84. if (this.props) {
  85. return `${k}({${Object.keys(this.props).join(",")}})`;
  86. }
  87. return `${k}(${this.value})`;
  88. }
  89. }
  90. export { diff };