Skip to content

Commit

Permalink
Introduced a utilify function 'spliceArray' to be used instead of
Browse files Browse the repository at this point in the history
'Array.prototype.splice', which results into an error -
"Maximum call stack size exceeded" when working with very big arrays.

Reported By: https://github.com/YeskaNova
Issue #51
  • Loading branch information
asheshv committed Dec 12, 2019
1 parent 7bf037e commit b09991b
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 6 deletions.
12 changes: 6 additions & 6 deletions src/infinite-tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { flatten, Node } from 'flattree';
import Clusterize from './clusterize';
import ensureArray from './ensure-array';
import extend from './extend';
import { get } from './utilities';
import { get, spliceArray } from './utilities';
import LookupTable from './lookup-table';
import { defaultRowRenderer } from './renderer';
import {
Expand Down Expand Up @@ -479,7 +479,7 @@ class InfiniteTree extends events.EventEmitter {
});

// Insert new child node at the specified index
parentNode.children.splice.apply(parentNode.children, [index, 0].concat(newNodes));
spliceArray(parentNode.children, newNodes, index, 0);

// Get the index of the first new node within the array of child nodes
index = parentNode.children.indexOf(newNodes[0]);
Expand All @@ -502,8 +502,8 @@ class InfiniteTree extends events.EventEmitter {
if (parentOffset >= 0) {
if (parentNode.state.open === true) {
// Update nodes & rows
this.nodes.splice.apply(this.nodes, [parentOffset + 1, deleteCount].concat(nodes));
this.rows.splice.apply(this.rows, [parentOffset + 1, deleteCount].concat(rows));
spliceArray(this.nodes, nodes, parentOffset + 1, deleteCount);
spliceArray(this.rows, rows, parentOffset + 1, deleteCount);
}

// Update the row corresponding to the parent node
Expand Down Expand Up @@ -1155,8 +1155,8 @@ class InfiniteTree extends events.EventEmitter {
}

// Update nodes & rows
this.nodes.splice.apply(this.nodes, [nodeIndex + 1, 0].concat(nodes));
this.rows.splice.apply(this.rows, [nodeIndex + 1, 0].concat(rows));
spliceArray(this.nodes, nodes, nodeIndex + 1, 0);
spliceArray(this.rows, rows, nodeIndex + 1, 0);

// Update the row corresponding to the node
this.rows[nodeIndex] = this.options.rowRenderer(node, this.options);
Expand Down
15 changes: 15 additions & 0 deletions src/utilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,21 @@ export const trim = (str, chars = ' \f\n\r\t\v') => {
return str;
};

// Use this function instead of Array.prototype.splice(...) as it results into
// "Maximum call stack size exceeded" when dealing with very big number.
export const spliceArray = (target, source, start, count) => {
let res = target.splice(start, count);

if (source && source.length) {
for (let idx = Math.floor(source.length / 10000); idx >= 0; idx--) {
target.splice.apply(target, [start, 0].concat(
source.slice(idx * 10000, (idx + 1) * 10000)
));
}
}
return res;
};

export const get = (function() {
const re = new RegExp(/[\w\-]+|\[[^\]]*\]+/g);

Expand Down

0 comments on commit b09991b

Please sign in to comment.