diff --git a/index.js b/index.js index 77668e0..6ea05f1 100644 --- a/index.js +++ b/index.js @@ -1,28 +1,53 @@ -exports.encode = exports.stringify = function (value) { - var values = [value]; +function encode(value) { + return JSON.stringify(tabulate(value)); +} + +function tabulate(value) { + var values = []; var table = []; + var indexMap = typeof Map === "function" && new Map; + + function getIndex(value) { + var index; + + if (indexMap) { + // If we have Map, use it instead of values.indexOf to accelerate + // object lookups. + index = indexMap.get(value); + if (typeof index === "undefined") { + index = values.push(value) - 1; + indexMap.set(value, index); + } + } else { + index = values.indexOf(value); + if (index < 0) { + index = values.push(value) - 1; + } + } + + return index; + } + + // Assign the root value to values[0]. + getIndex(value); for (var v = 0; v < values.length; ++v) { value = values[v]; + if (value && typeof value === "object") { var copy = table[v] = Array.isArray(value) ? [] : {}; Object.keys(value).forEach(function (key) { - var child = value[key]; - var index = values.indexOf(child); - if (index < 0) { - index = values.push(child) - 1; - } - copy[key] = index; + copy[key] = getIndex(value[key]); }); } else { table[v] = value; } } - return JSON.stringify(table); -}; + return table; +} -exports.decode = exports.parse = function (encoding) { +function decode(encoding) { var table = JSON.parse(encoding); table.forEach(function (entry) { @@ -34,4 +59,7 @@ exports.decode = exports.parse = function (encoding) { }); return table[0]; -}; +} + +exports.encode = exports.stringify = encode; +exports.decode = exports.parse = decode;