index.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /* eslint-disable */
  2. // @ts-nocheck
  3. var LIMIT_REPLACE_NODE = "[...]";
  4. var CIRCULAR_REPLACE_NODE = { result: "[Circular]" };
  5. var arr = [];
  6. var replacerStack = [];
  7. const encoder = new TextEncoder();
  8. function defaultOptions() {
  9. return {
  10. depthLimit: Number.MAX_SAFE_INTEGER,
  11. edgesLimit: Number.MAX_SAFE_INTEGER,
  12. };
  13. }
  14. function encodeString(str) {
  15. return encoder.encode(str);
  16. }
  17. // Regular stringify
  18. export function serialize(obj, errorContext, replacer, spacer, options) {
  19. try {
  20. const str = JSON.stringify(obj, replacer, spacer);
  21. return encodeString(str);
  22. }
  23. catch (e) {
  24. // Fall back to more complex stringify if circular reference
  25. if (!e.message?.includes("Converting circular structure to JSON")) {
  26. console.warn(`[WARNING]: LangSmith received unserializable value.${errorContext ? `\nContext: ${errorContext}` : ""}`);
  27. return encodeString("[Unserializable]");
  28. }
  29. console.warn(`[WARNING]: LangSmith received circular JSON. This will decrease tracer performance. ${errorContext ? `\nContext: ${errorContext}` : ""}`);
  30. if (typeof options === "undefined") {
  31. options = defaultOptions();
  32. }
  33. decirc(obj, "", 0, [], undefined, 0, options);
  34. let res;
  35. try {
  36. if (replacerStack.length === 0) {
  37. res = JSON.stringify(obj, replacer, spacer);
  38. }
  39. else {
  40. res = JSON.stringify(obj, replaceGetterValues(replacer), spacer);
  41. }
  42. }
  43. catch (_) {
  44. return encodeString("[unable to serialize, circular reference is too complex to analyze]");
  45. }
  46. finally {
  47. while (arr.length !== 0) {
  48. const part = arr.pop();
  49. if (part.length === 4) {
  50. Object.defineProperty(part[0], part[1], part[3]);
  51. }
  52. else {
  53. part[0][part[1]] = part[2];
  54. }
  55. }
  56. }
  57. return encodeString(res);
  58. }
  59. }
  60. function setReplace(replace, val, k, parent) {
  61. var propertyDescriptor = Object.getOwnPropertyDescriptor(parent, k);
  62. if (propertyDescriptor.get !== undefined) {
  63. if (propertyDescriptor.configurable) {
  64. Object.defineProperty(parent, k, { value: replace });
  65. arr.push([parent, k, val, propertyDescriptor]);
  66. }
  67. else {
  68. replacerStack.push([val, k, replace]);
  69. }
  70. }
  71. else {
  72. parent[k] = replace;
  73. arr.push([parent, k, val]);
  74. }
  75. }
  76. function decirc(val, k, edgeIndex, stack, parent, depth, options) {
  77. depth += 1;
  78. var i;
  79. if (typeof val === "object" && val !== null) {
  80. for (i = 0; i < stack.length; i++) {
  81. if (stack[i] === val) {
  82. setReplace(CIRCULAR_REPLACE_NODE, val, k, parent);
  83. return;
  84. }
  85. }
  86. if (typeof options.depthLimit !== "undefined" &&
  87. depth > options.depthLimit) {
  88. setReplace(LIMIT_REPLACE_NODE, val, k, parent);
  89. return;
  90. }
  91. if (typeof options.edgesLimit !== "undefined" &&
  92. edgeIndex + 1 > options.edgesLimit) {
  93. setReplace(LIMIT_REPLACE_NODE, val, k, parent);
  94. return;
  95. }
  96. stack.push(val);
  97. // Optimize for Arrays. Big arrays could kill the performance otherwise!
  98. if (Array.isArray(val)) {
  99. for (i = 0; i < val.length; i++) {
  100. decirc(val[i], i, i, stack, val, depth, options);
  101. }
  102. }
  103. else {
  104. var keys = Object.keys(val);
  105. for (i = 0; i < keys.length; i++) {
  106. var key = keys[i];
  107. decirc(val[key], key, i, stack, val, depth, options);
  108. }
  109. }
  110. stack.pop();
  111. }
  112. }
  113. // Stable-stringify
  114. function compareFunction(a, b) {
  115. if (a < b) {
  116. return -1;
  117. }
  118. if (a > b) {
  119. return 1;
  120. }
  121. return 0;
  122. }
  123. function deterministicStringify(obj, replacer, spacer, options) {
  124. if (typeof options === "undefined") {
  125. options = defaultOptions();
  126. }
  127. var tmp = deterministicDecirc(obj, "", 0, [], undefined, 0, options) || obj;
  128. var res;
  129. try {
  130. if (replacerStack.length === 0) {
  131. res = JSON.stringify(tmp, replacer, spacer);
  132. }
  133. else {
  134. res = JSON.stringify(tmp, replaceGetterValues(replacer), spacer);
  135. }
  136. }
  137. catch (_) {
  138. return JSON.stringify("[unable to serialize, circular reference is too complex to analyze]");
  139. }
  140. finally {
  141. // Ensure that we restore the object as it was.
  142. while (arr.length !== 0) {
  143. var part = arr.pop();
  144. if (part.length === 4) {
  145. Object.defineProperty(part[0], part[1], part[3]);
  146. }
  147. else {
  148. part[0][part[1]] = part[2];
  149. }
  150. }
  151. }
  152. return res;
  153. }
  154. function deterministicDecirc(val, k, edgeIndex, stack, parent, depth, options) {
  155. depth += 1;
  156. var i;
  157. if (typeof val === "object" && val !== null) {
  158. for (i = 0; i < stack.length; i++) {
  159. if (stack[i] === val) {
  160. setReplace(CIRCULAR_REPLACE_NODE, val, k, parent);
  161. return;
  162. }
  163. }
  164. try {
  165. if (typeof val.toJSON === "function") {
  166. return;
  167. }
  168. }
  169. catch (_) {
  170. return;
  171. }
  172. if (typeof options.depthLimit !== "undefined" &&
  173. depth > options.depthLimit) {
  174. setReplace(LIMIT_REPLACE_NODE, val, k, parent);
  175. return;
  176. }
  177. if (typeof options.edgesLimit !== "undefined" &&
  178. edgeIndex + 1 > options.edgesLimit) {
  179. setReplace(LIMIT_REPLACE_NODE, val, k, parent);
  180. return;
  181. }
  182. stack.push(val);
  183. // Optimize for Arrays. Big arrays could kill the performance otherwise!
  184. if (Array.isArray(val)) {
  185. for (i = 0; i < val.length; i++) {
  186. deterministicDecirc(val[i], i, i, stack, val, depth, options);
  187. }
  188. }
  189. else {
  190. // Create a temporary object in the required way
  191. var tmp = {};
  192. var keys = Object.keys(val).sort(compareFunction);
  193. for (i = 0; i < keys.length; i++) {
  194. var key = keys[i];
  195. deterministicDecirc(val[key], key, i, stack, val, depth, options);
  196. tmp[key] = val[key];
  197. }
  198. if (typeof parent !== "undefined") {
  199. arr.push([parent, k, val]);
  200. parent[k] = tmp;
  201. }
  202. else {
  203. return tmp;
  204. }
  205. }
  206. stack.pop();
  207. }
  208. }
  209. // wraps replacer function to handle values we couldn't replace
  210. // and mark them as replaced value
  211. function replaceGetterValues(replacer) {
  212. replacer =
  213. typeof replacer !== "undefined"
  214. ? replacer
  215. : function (k, v) {
  216. return v;
  217. };
  218. return function (key, val) {
  219. if (replacerStack.length > 0) {
  220. for (var i = 0; i < replacerStack.length; i++) {
  221. var part = replacerStack[i];
  222. if (part[1] === key && part[0] === val) {
  223. val = part[2];
  224. replacerStack.splice(i, 1);
  225. break;
  226. }
  227. }
  228. }
  229. return replacer.call(this, key, val);
  230. };
  231. }