stringify.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // lifted from here: https://github.com/lucagez/slow-json-stringify
  2. var _prepare = function(e) {
  3. var r = JSON.stringify(e, function(e, r) {
  4. return r.isSJS ? r.type + "__sjs" : r
  5. });
  6. return {
  7. preparedString: r,
  8. preparedSchema: JSON.parse(r)
  9. }
  10. },
  11. _find = function(path) {
  12. for (var length = path.length, str = "obj", i = 0; i < length; i++) str = str.replace(/^/, "("), str += " || {})." + path[i];
  13. return just.vm.runScript("((obj) => " + str + ")")
  14. },
  15. _makeArraySerializer = function(e) {
  16. return e instanceof Function ? function(r) {
  17. for (var n = "", t = r.length, a = 0; a < t - 1; a++) n += e(r[a]) + ",";
  18. return "[" + (n += e(r[t - 1])) + "]"
  19. } : function(e) {
  20. return JSON.stringify(e)
  21. }
  22. },
  23. TYPES = ["number", "string", "boolean", "array", "null"],
  24. attr = function(e, r) {
  25. if (!TYPES.includes(e)) throw new Error('Expected one of: "number", "string", "boolean", "null". received "' + e + '" instead');
  26. var n = r || function(e) {
  27. return e
  28. };
  29. return {
  30. isSJS: !0,
  31. type: e,
  32. serializer: "array" === e ? _makeArraySerializer(r) : n
  33. }
  34. },
  35. defaultRegex = new RegExp('\\n|\\r|\\t|\\"|\\\\', "gm"),
  36. escape = function(e) {
  37. return void 0 === e && (e = defaultRegex),
  38. function(r) {
  39. return r.replace(e, function(e) {
  40. return "\\" + e
  41. })
  42. }
  43. },
  44. _makeQueue = function(e, r) {
  45. var n = [];
  46. return function e(t, a) {
  47. if (void 0 === a && (a = []), !/__sjs/.test(t)) return Object.keys(t).map(function(r) {
  48. return e(t[r], a.concat([r]))
  49. });
  50. var i = Array.from(a),
  51. u = _find(i),
  52. s = u(r);
  53. n.push({
  54. serializer: s.serializer,
  55. find: u,
  56. name: a[a.length - 1]
  57. })
  58. }(e), n
  59. },
  60. _makeChunks = function(e, r) {
  61. return e.replace(/"\w+__sjs"/gm, function(e) {
  62. return /string/.test(e) ? '"__par__"' : "__par__"
  63. }).split("__par__").map(function(e, n, t) {
  64. var a = '("' + (r[n] || {}).name + '":("?))$',
  65. i = "(,?)" + a,
  66. u = /^("}|})/.test(t[n + 1] || ""),
  67. s = new RegExp(u ? i : a),
  68. f = /^(\"\,|\,|\")/;
  69. return {
  70. flag: !1,
  71. pure: e,
  72. prevUndef: e.replace(f, ""),
  73. isUndef: e.replace(s, ""),
  74. bothUndef: e.replace(f, "").replace(s, "")
  75. }
  76. })
  77. },
  78. _select = function(e) {
  79. return function(r, n) {
  80. var t = e[n];
  81. return void 0 !== r ? t.flag ? t.prevUndef + r : t.pure + r : (e[n + 1].flag = !0, t.flag ? t.bothUndef : t.isUndef)
  82. }
  83. },
  84. sjs = function(e) {
  85. var r = _prepare(e),
  86. n = r.preparedString,
  87. t = _makeQueue(r.preparedSchema, e),
  88. a = _makeChunks(n, t),
  89. i = _select(a),
  90. u = t.length;
  91. return function(e) {
  92. for (var r = "", n = 0; n !== u;) {
  93. var s = t[n],
  94. f = s.serializer,
  95. p = (0, s.find)(e);
  96. r += i(f(p), n), n += 1
  97. }
  98. var o = a[a.length - 1];
  99. return r + (o.flag ? o.prevUndef : o.pure)
  100. }
  101. };
  102. exports.sjs = sjs, exports.attr = attr, exports.escape = escape;