@ensdomains/merkle-builder 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -811,89 +811,57 @@ function mimcHash(v) {
811
811
 
812
812
  // src/surgery.ts
813
813
  function pluckLimbs(node, depth) {
814
- if (!node || depth <= 0) return { trunk: node, limbs: [] };
815
- const queue = [];
816
- if (isBranch(node)) {
817
- queue.push([node, []]);
818
- } else if (isExtension(node)) {
819
- if (node.path.length >= depth) {
820
- const extension = node.path.length === depth ? node.child : { path: node.path.subarray(depth), child: node.child };
821
- return {
822
- trunk: void 0,
823
- limbs: [[node.path.subarray(0, depth), extension]]
824
- };
825
- }
826
- queue.push([node.child, [...node.path]]);
827
- } else if (node.path.length >= depth) {
828
- const leaf = newLeaf(node.path.subarray(depth), node.data);
829
- return {
830
- trunk: void 0,
831
- limbs: [[node.path.subarray(0, depth), leaf]]
832
- };
833
- }
834
814
  const limbs = [];
835
- while (queue.length) {
836
- const [parent, path] = queue.pop();
837
- parent.children.forEach((x, i) => {
838
- if (!x) return;
839
- if (path.length + 1 === depth) {
840
- parent.children[i] = void 0;
841
- limbs.push([Uint8Array.of(...path, i), x]);
842
- } else if (isBranch(x)) {
843
- queue.push([x, [...path, i]]);
844
- } else if (isExtension(x)) {
845
- const full = [...path, i, ...x.path];
846
- if (full.length >= depth) {
847
- const { cache, ...branch } = x.child;
848
- const child = newBranch();
849
- if (cache) child.cache = cache;
850
- parent.children[i] = { path: x.path, child };
851
- limbs.push([new Uint8Array(full.slice(0, depth)), branch]);
852
- } else {
853
- queue.push([x.child, full]);
854
- }
815
+ if (node && depth > 0) pluck(node, []);
816
+ return limbs;
817
+ function pluck(node2, path, ext = false) {
818
+ if (path.length >= depth) {
819
+ if (ext && "cache" in node2) {
820
+ node2 = { children: node2.children };
855
821
  }
856
- });
822
+ limbs.push([new Uint8Array(path.slice(0, depth)), node2]);
823
+ return true;
824
+ } else if (isBranch(node2)) {
825
+ node2.children.forEach((x, i, v) => {
826
+ if (x && pluck(x, [...path, i])) {
827
+ v[i] = void 0;
828
+ }
829
+ });
830
+ } else if (isExtension(node2) && pluck(node2.child, [...path, ...node2.path], true)) {
831
+ node2.child = { ...node2.child, ...newBranch() };
832
+ }
857
833
  }
858
- return { trunk: node, limbs };
859
834
  }
860
835
  function graftLimb(trunk, [path, limb]) {
861
- if (!path.length) return limb;
862
- if (!trunk) {
863
- if (isBranch(limb)) {
864
- return { path: path.slice(), child: limb };
865
- } else {
866
- const copy = { ...limb };
867
- copy.path = concat(path, copy.path);
868
- return copy;
869
- }
870
- }
871
- let index = 0;
872
- let parent = trunk;
873
- while (index < path.length - 1) {
874
- if (isBranch(parent)) {
875
- parent = parent.children[path[index++]];
876
- } else if (isExtension(parent)) {
877
- index += parent.path.length;
878
- if (index >= path.length) break;
879
- parent = parent.child;
836
+ if (!trunk || !path.length) throw new Error("invalid graft");
837
+ let part = [];
838
+ let parent = void 0;
839
+ let cursor = trunk;
840
+ while (part.length < path.length) {
841
+ if (isBranch(cursor)) {
842
+ const i = path[part.length];
843
+ part.push(i);
844
+ parent = cursor;
845
+ cursor = cursor.children[i];
846
+ if (isExtension(cursor)) {
847
+ parent = cursor;
848
+ part.push(...cursor.path);
849
+ cursor = cursor.child;
850
+ }
851
+ } else if (isExtension(cursor)) {
852
+ parent = cursor;
853
+ part.push(...cursor.path);
854
+ cursor = cursor.child;
880
855
  } else {
881
856
  break;
882
857
  }
883
858
  }
884
- if (isExtension(parent)) {
885
- if (!isBranch(limb)) throw new RangeError("expected branch");
859
+ if (!path.every((x, i) => x === part[i])) throw new Error("invalid path");
860
+ if (isBranch(parent)) {
861
+ parent.children[path[path.length - 1]] = limb;
862
+ } else if (isExtension(parent)) {
863
+ if (!isBranch(limb)) throw new Error("invalid limb");
886
864
  parent.child.children = limb.children;
887
- } else if (isBranch(parent)) {
888
- if (isBranch(limb)) {
889
- parent.children[path[index]] = index + 1 == path.length ? limb : { path: path.slice(index + 1), child: limb };
890
- } else {
891
- const copy = { ...limb };
892
- copy.path = concat(path.subarray(index + 1), copy.path);
893
- parent.children[path[index]] = copy;
894
- }
895
- } else {
896
- throw new RangeError("invalid graft location");
897
865
  }
898
866
  return trunk;
899
867
  }
package/dist/index.d.cts CHANGED
@@ -75,10 +75,7 @@ declare function insertBytes(node: MaybeNode, slot: Uint8Array, value: Uint8Arra
75
75
  declare function mimcHash(v: bigint[]): bigint;
76
76
 
77
77
  type Limb = [path: Uint8Array, node: Node];
78
- declare function pluckLimbs(node: MaybeNode, depth: number): {
79
- trunk: MaybeNode;
80
- limbs: Limb[];
81
- };
78
+ declare function pluckLimbs(node: MaybeNode, depth: number): Limb[];
82
79
  declare function graftLimb(trunk: MaybeNode, [path, limb]: Limb): Node;
83
80
 
84
81
  type Hex = `0x${string}`;
package/dist/index.d.ts CHANGED
@@ -75,10 +75,7 @@ declare function insertBytes(node: MaybeNode, slot: Uint8Array, value: Uint8Arra
75
75
  declare function mimcHash(v: bigint[]): bigint;
76
76
 
77
77
  type Limb = [path: Uint8Array, node: Node];
78
- declare function pluckLimbs(node: MaybeNode, depth: number): {
79
- trunk: MaybeNode;
80
- limbs: Limb[];
81
- };
78
+ declare function pluckLimbs(node: MaybeNode, depth: number): Limb[];
82
79
  declare function graftLimb(trunk: MaybeNode, [path, limb]: Limb): Node;
83
80
 
84
81
  type Hex = `0x${string}`;
package/dist/index.js CHANGED
@@ -749,89 +749,57 @@ function mimcHash(v) {
749
749
 
750
750
  // src/surgery.ts
751
751
  function pluckLimbs(node, depth) {
752
- if (!node || depth <= 0) return { trunk: node, limbs: [] };
753
- const queue = [];
754
- if (isBranch(node)) {
755
- queue.push([node, []]);
756
- } else if (isExtension(node)) {
757
- if (node.path.length >= depth) {
758
- const extension = node.path.length === depth ? node.child : { path: node.path.subarray(depth), child: node.child };
759
- return {
760
- trunk: void 0,
761
- limbs: [[node.path.subarray(0, depth), extension]]
762
- };
763
- }
764
- queue.push([node.child, [...node.path]]);
765
- } else if (node.path.length >= depth) {
766
- const leaf = newLeaf(node.path.subarray(depth), node.data);
767
- return {
768
- trunk: void 0,
769
- limbs: [[node.path.subarray(0, depth), leaf]]
770
- };
771
- }
772
752
  const limbs = [];
773
- while (queue.length) {
774
- const [parent, path] = queue.pop();
775
- parent.children.forEach((x, i) => {
776
- if (!x) return;
777
- if (path.length + 1 === depth) {
778
- parent.children[i] = void 0;
779
- limbs.push([Uint8Array.of(...path, i), x]);
780
- } else if (isBranch(x)) {
781
- queue.push([x, [...path, i]]);
782
- } else if (isExtension(x)) {
783
- const full = [...path, i, ...x.path];
784
- if (full.length >= depth) {
785
- const { cache, ...branch } = x.child;
786
- const child = newBranch();
787
- if (cache) child.cache = cache;
788
- parent.children[i] = { path: x.path, child };
789
- limbs.push([new Uint8Array(full.slice(0, depth)), branch]);
790
- } else {
791
- queue.push([x.child, full]);
792
- }
753
+ if (node && depth > 0) pluck(node, []);
754
+ return limbs;
755
+ function pluck(node2, path, ext = false) {
756
+ if (path.length >= depth) {
757
+ if (ext && "cache" in node2) {
758
+ node2 = { children: node2.children };
793
759
  }
794
- });
760
+ limbs.push([new Uint8Array(path.slice(0, depth)), node2]);
761
+ return true;
762
+ } else if (isBranch(node2)) {
763
+ node2.children.forEach((x, i, v) => {
764
+ if (x && pluck(x, [...path, i])) {
765
+ v[i] = void 0;
766
+ }
767
+ });
768
+ } else if (isExtension(node2) && pluck(node2.child, [...path, ...node2.path], true)) {
769
+ node2.child = { ...node2.child, ...newBranch() };
770
+ }
795
771
  }
796
- return { trunk: node, limbs };
797
772
  }
798
773
  function graftLimb(trunk, [path, limb]) {
799
- if (!path.length) return limb;
800
- if (!trunk) {
801
- if (isBranch(limb)) {
802
- return { path: path.slice(), child: limb };
803
- } else {
804
- const copy = { ...limb };
805
- copy.path = concat(path, copy.path);
806
- return copy;
807
- }
808
- }
809
- let index = 0;
810
- let parent = trunk;
811
- while (index < path.length - 1) {
812
- if (isBranch(parent)) {
813
- parent = parent.children[path[index++]];
814
- } else if (isExtension(parent)) {
815
- index += parent.path.length;
816
- if (index >= path.length) break;
817
- parent = parent.child;
774
+ if (!trunk || !path.length) throw new Error("invalid graft");
775
+ let part = [];
776
+ let parent = void 0;
777
+ let cursor = trunk;
778
+ while (part.length < path.length) {
779
+ if (isBranch(cursor)) {
780
+ const i = path[part.length];
781
+ part.push(i);
782
+ parent = cursor;
783
+ cursor = cursor.children[i];
784
+ if (isExtension(cursor)) {
785
+ parent = cursor;
786
+ part.push(...cursor.path);
787
+ cursor = cursor.child;
788
+ }
789
+ } else if (isExtension(cursor)) {
790
+ parent = cursor;
791
+ part.push(...cursor.path);
792
+ cursor = cursor.child;
818
793
  } else {
819
794
  break;
820
795
  }
821
796
  }
822
- if (isExtension(parent)) {
823
- if (!isBranch(limb)) throw new RangeError("expected branch");
797
+ if (!path.every((x, i) => x === part[i])) throw new Error("invalid path");
798
+ if (isBranch(parent)) {
799
+ parent.children[path[path.length - 1]] = limb;
800
+ } else if (isExtension(parent)) {
801
+ if (!isBranch(limb)) throw new Error("invalid limb");
824
802
  parent.child.children = limb.children;
825
- } else if (isBranch(parent)) {
826
- if (isBranch(limb)) {
827
- parent.children[path[index]] = index + 1 == path.length ? limb : { path: path.slice(index + 1), child: limb };
828
- } else {
829
- const copy = { ...limb };
830
- copy.path = concat(path.subarray(index + 1), copy.path);
831
- parent.children[path[index]] = copy;
832
- }
833
- } else {
834
- throw new RangeError("invalid graft location");
835
803
  }
836
804
  return trunk;
837
805
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ensdomains/merkle-builder",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "Low-level Merkle-Patricia storage trie implementation",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",