json-ext.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  3. typeof define === 'function' && define.amd ? define(factory) :
  4. (global.jsonExt = factory());
  5. }(typeof globalThis != 'undefined' ? globalThis : typeof window != 'undefined' ? window : typeof global != 'undefined' ? global : typeof self != 'undefined' ? self : this, (function () {
  6. // src/utils.js
  7. function isIterable(value) {
  8. return typeof value === "object" && value !== null && (typeof value[Symbol.iterator] === "function" || typeof value[Symbol.asyncIterator] === "function");
  9. }
  10. function replaceValue(holder, key, value, replacer) {
  11. if (value && typeof value.toJSON === "function") {
  12. value = value.toJSON();
  13. }
  14. if (replacer !== null) {
  15. value = replacer.call(holder, String(key), value);
  16. }
  17. switch (typeof value) {
  18. case "function":
  19. case "symbol":
  20. value = void 0;
  21. break;
  22. case "object":
  23. if (value !== null) {
  24. const cls = value.constructor;
  25. if (cls === String || cls === Number || cls === Boolean) {
  26. value = value.valueOf();
  27. }
  28. }
  29. break;
  30. }
  31. return value;
  32. }
  33. function normalizeReplacer(replacer) {
  34. if (typeof replacer === "function") {
  35. return replacer;
  36. }
  37. if (Array.isArray(replacer)) {
  38. const allowlist = new Set(
  39. replacer.map((item) => {
  40. const cls = item && item.constructor;
  41. return cls === String || cls === Number ? String(item) : null;
  42. }).filter((item) => typeof item === "string")
  43. );
  44. return [...allowlist];
  45. }
  46. return null;
  47. }
  48. function normalizeSpace(space) {
  49. if (typeof space === "number") {
  50. if (!Number.isFinite(space) || space < 1) {
  51. return false;
  52. }
  53. return " ".repeat(Math.min(space, 10));
  54. }
  55. if (typeof space === "string") {
  56. return space.slice(0, 10) || false;
  57. }
  58. return false;
  59. }
  60. function normalizeStringifyOptions(optionsOrReplacer, space) {
  61. if (optionsOrReplacer === null || Array.isArray(optionsOrReplacer) || typeof optionsOrReplacer !== "object") {
  62. optionsOrReplacer = {
  63. replacer: optionsOrReplacer,
  64. space
  65. };
  66. }
  67. let replacer = normalizeReplacer(optionsOrReplacer.replacer);
  68. let getKeys = Object.keys;
  69. if (Array.isArray(replacer)) {
  70. const allowlist = replacer;
  71. getKeys = () => allowlist;
  72. replacer = null;
  73. }
  74. return {
  75. ...optionsOrReplacer,
  76. replacer,
  77. getKeys,
  78. space: normalizeSpace(optionsOrReplacer.space)
  79. };
  80. }
  81. function resolveStringifyMode(mode = "json") {
  82. if (mode === "json" || mode === "jsonl") {
  83. return mode;
  84. }
  85. throw new TypeError('Invalid options: `mode` should be "json" or "jsonl"');
  86. }
  87. // src/parse-chunked.js
  88. var NO_VALUE = /* @__PURE__ */ Symbol("empty");
  89. var STACK_OBJECT = 1;
  90. var STACK_ARRAY = 2;
  91. var MODE_JSON = 0;
  92. var MODE_JSONL = 1;
  93. var MODE_JSONL_AUTO = 2;
  94. var decoder = new TextDecoder();
  95. function adjustPosition(error, jsonParseOffset) {
  96. if (error.name === "SyntaxError" && jsonParseOffset) {
  97. error.message = error.message.replace(
  98. /at position (\d+)/,
  99. (_, pos) => "at position " + (Number(pos) + jsonParseOffset)
  100. );
  101. }
  102. return error;
  103. }
  104. function append(array, elements) {
  105. const initialLength = array.length;
  106. array.length += elements.length;
  107. for (let i = 0; i < elements.length; i++) {
  108. array[initialLength + i] = elements[i];
  109. }
  110. }
  111. function resolveParseMode(mode) {
  112. switch (mode) {
  113. case "json":
  114. return MODE_JSON;
  115. case "jsonl":
  116. return MODE_JSONL;
  117. case "auto":
  118. return MODE_JSONL_AUTO;
  119. default:
  120. throw new TypeError('Invalid options: `mode` should be "json", "jsonl", or "auto"');
  121. }
  122. }
  123. function parseChunkedOptions(value) {
  124. const options = typeof value === "function" ? { reviver: value } : value || {};
  125. return {
  126. mode: resolveParseMode(options.mode ?? "json"),
  127. reviver: options.reviver ?? null,
  128. onRootValue: options.onRootValue ?? null,
  129. onChunk: options.onChunk ?? null
  130. };
  131. }
  132. function applyReviver(value, reviver) {
  133. return walk({ "": value }, "", value);
  134. function walk(holder, key, value2) {
  135. if (value2 && typeof value2 === "object") {
  136. for (const childKey of Object.keys(value2)) {
  137. const childValue = value2[childKey];
  138. const newValue = walk(value2, childKey, childValue);
  139. if (newValue === void 0) {
  140. delete value2[childKey];
  141. } else if (newValue !== childValue) {
  142. value2[childKey] = newValue;
  143. }
  144. }
  145. }
  146. return reviver.call(holder, key, value2);
  147. }
  148. }
  149. async function parseChunked(chunkEmitter, optionsOrReviver) {
  150. const { mode, reviver, onRootValue, onChunk } = parseChunkedOptions(optionsOrReviver);
  151. const iterable = typeof chunkEmitter === "function" ? chunkEmitter() : chunkEmitter;
  152. if (isIterable(iterable)) {
  153. const parser = createChunkParser(mode, reviver, onRootValue, onChunk);
  154. try {
  155. for await (const chunk of iterable) {
  156. if (typeof chunk !== "string" && !ArrayBuffer.isView(chunk)) {
  157. throw new TypeError("Invalid chunk: Expected string, TypedArray or Buffer");
  158. }
  159. parser.push(chunk);
  160. }
  161. return parser.finish();
  162. } catch (e) {
  163. throw adjustPosition(e, parser.jsonParseOffset);
  164. }
  165. }
  166. throw new TypeError(
  167. "Invalid chunk emitter: Expected an Iterable, AsyncIterable, generator, async generator, or a function returning an Iterable or AsyncIterable"
  168. );
  169. }
  170. function createChunkParser(parseMode, reviver, onRootValue, onChunk) {
  171. let rootValues = parseMode === MODE_JSONL ? [] : null;
  172. let rootValuesCount = 0;
  173. let currentRootValue = NO_VALUE;
  174. let currentRootValueCursor = null;
  175. let consumedChunkLength = 0;
  176. let parsedChunkLength = 0;
  177. let prevArray = null;
  178. let prevArraySlices = [];
  179. let stack = new Array(100);
  180. let lastFlushDepth = 0;
  181. let flushDepth = 0;
  182. let stateString = false;
  183. let stateStringEscape = false;
  184. let seenNonWhiteSpace = false;
  185. let allowNewRootValue = true;
  186. let pendingByteSeq = null;
  187. let pendingChunk = null;
  188. let jsonParseOffset = 0;
  189. const state = Object.freeze({
  190. get mode() {
  191. return parseMode === MODE_JSONL ? "jsonl" : "json";
  192. },
  193. get rootValuesCount() {
  194. return rootValuesCount;
  195. },
  196. get consumed() {
  197. return consumedChunkLength;
  198. },
  199. get parsed() {
  200. return parsedChunkLength;
  201. }
  202. });
  203. return {
  204. push,
  205. finish,
  206. state,
  207. get jsonParseOffset() {
  208. return jsonParseOffset;
  209. }
  210. };
  211. function startRootValue(fragment) {
  212. if (!allowNewRootValue) {
  213. jsonParseOffset -= 2;
  214. JSON.parse("[]" + fragment);
  215. }
  216. if (currentRootValue !== NO_VALUE && parseMode === MODE_JSONL_AUTO) {
  217. parseMode = MODE_JSONL;
  218. rootValues = [currentRootValue];
  219. }
  220. allowNewRootValue = false;
  221. currentRootValue = JSON.parse(fragment);
  222. }
  223. function finishRootValue() {
  224. rootValuesCount++;
  225. if (typeof reviver === "function") {
  226. currentRootValue = applyReviver(currentRootValue, reviver);
  227. }
  228. if (typeof onRootValue === "function") {
  229. onRootValue(currentRootValue, state);
  230. } else if (parseMode === MODE_JSONL) {
  231. rootValues.push(currentRootValue);
  232. }
  233. }
  234. function mergeArraySlices() {
  235. if (prevArray === null) {
  236. return;
  237. }
  238. if (prevArraySlices.length !== 0) {
  239. const newArray = prevArraySlices.length === 1 ? prevArray.concat(prevArraySlices[0]) : prevArray.concat(...prevArraySlices);
  240. if (currentRootValueCursor.prev !== null) {
  241. currentRootValueCursor.prev.value[currentRootValueCursor.key] = newArray;
  242. } else {
  243. currentRootValue = newArray;
  244. }
  245. currentRootValueCursor.value = newArray;
  246. prevArraySlices = [];
  247. }
  248. prevArray = null;
  249. }
  250. function parseAndAppend(fragment, wrap) {
  251. if (stack[lastFlushDepth - 1] === STACK_OBJECT) {
  252. if (wrap) {
  253. jsonParseOffset--;
  254. fragment = "{" + fragment + "}";
  255. }
  256. Object.assign(currentRootValueCursor.value, JSON.parse(fragment));
  257. } else {
  258. if (wrap) {
  259. jsonParseOffset--;
  260. fragment = "[" + fragment + "]";
  261. }
  262. if (prevArray === currentRootValueCursor.value) {
  263. prevArraySlices.push(JSON.parse(fragment));
  264. } else {
  265. append(currentRootValueCursor.value, JSON.parse(fragment));
  266. prevArray = currentRootValueCursor.value;
  267. }
  268. }
  269. }
  270. function prepareAddition(fragment) {
  271. const { value } = currentRootValueCursor;
  272. const expectComma = Array.isArray(value) ? value.length !== 0 : Object.keys(value).length !== 0;
  273. if (expectComma) {
  274. if (fragment[0] === ",") {
  275. jsonParseOffset++;
  276. return fragment.slice(1);
  277. }
  278. if (fragment[0] !== "}" && fragment[0] !== "]") {
  279. jsonParseOffset -= 3;
  280. return "[[]" + fragment;
  281. }
  282. }
  283. return fragment;
  284. }
  285. function flush(chunk, start, end) {
  286. let fragment = chunk.slice(start, end);
  287. jsonParseOffset = consumedChunkLength + start;
  288. parsedChunkLength += end - start;
  289. if (pendingChunk !== null) {
  290. fragment = pendingChunk + fragment;
  291. jsonParseOffset -= pendingChunk.length;
  292. parsedChunkLength += pendingChunk.length;
  293. pendingChunk = null;
  294. }
  295. if (flushDepth === lastFlushDepth) {
  296. if (lastFlushDepth === 0) {
  297. startRootValue(fragment);
  298. } else {
  299. parseAndAppend(prepareAddition(fragment), true);
  300. }
  301. } else if (flushDepth > lastFlushDepth) {
  302. for (let i = flushDepth - 1; i >= lastFlushDepth; i--) {
  303. fragment += stack[i] === STACK_OBJECT ? "}" : "]";
  304. }
  305. if (lastFlushDepth === 0) {
  306. startRootValue(fragment);
  307. currentRootValueCursor = {
  308. value: currentRootValue,
  309. key: null,
  310. prev: null
  311. };
  312. } else {
  313. parseAndAppend(prepareAddition(fragment), true);
  314. mergeArraySlices();
  315. }
  316. for (let i = lastFlushDepth || 1; i < flushDepth; i++) {
  317. let { value } = currentRootValueCursor;
  318. let key = null;
  319. if (stack[i - 1] === STACK_OBJECT) {
  320. for (key in value) ;
  321. value = value[key];
  322. } else {
  323. key = value.length - 1;
  324. value = value[key];
  325. }
  326. currentRootValueCursor = {
  327. value,
  328. key,
  329. prev: currentRootValueCursor
  330. };
  331. }
  332. } else {
  333. fragment = prepareAddition(fragment);
  334. for (let i = lastFlushDepth - 1; i >= flushDepth; i--) {
  335. jsonParseOffset--;
  336. fragment = (stack[i] === STACK_OBJECT ? "{" : "[") + fragment;
  337. }
  338. parseAndAppend(fragment, false);
  339. mergeArraySlices();
  340. for (let i = lastFlushDepth - 1; i >= flushDepth; i--) {
  341. currentRootValueCursor = currentRootValueCursor.prev;
  342. }
  343. }
  344. if (flushDepth === 0) {
  345. finishRootValue();
  346. }
  347. lastFlushDepth = flushDepth;
  348. seenNonWhiteSpace = false;
  349. }
  350. function ensureChunkString(chunk) {
  351. if (typeof chunk !== "string") {
  352. if (pendingByteSeq !== null) {
  353. const origRawChunk = chunk;
  354. chunk = new Uint8Array(pendingByteSeq.length + origRawChunk.length);
  355. chunk.set(pendingByteSeq);
  356. chunk.set(origRawChunk, pendingByteSeq.length);
  357. pendingByteSeq = null;
  358. }
  359. if (chunk[chunk.length - 1] > 127) {
  360. for (let seqLength = 0; seqLength < chunk.length; seqLength++) {
  361. const byte = chunk[chunk.length - 1 - seqLength];
  362. if (byte >> 6 === 3) {
  363. seqLength++;
  364. if (seqLength !== 4 && byte >> 3 === 30 || seqLength !== 3 && byte >> 4 === 14 || seqLength !== 2 && byte >> 5 === 6) {
  365. pendingByteSeq = chunk.slice(chunk.length - seqLength);
  366. chunk = chunk.subarray(0, -seqLength);
  367. }
  368. break;
  369. }
  370. }
  371. }
  372. chunk = decoder.decode(chunk);
  373. }
  374. return chunk;
  375. }
  376. function push(chunk) {
  377. chunk = ensureChunkString(chunk);
  378. const chunkLength = chunk.length;
  379. const prevParsedChunkLength = parsedChunkLength;
  380. let lastFlushPoint = 0;
  381. let flushPoint = 0;
  382. scan: for (let i = 0; i < chunkLength; i++) {
  383. if (stateString) {
  384. for (; i < chunkLength; i++) {
  385. if (stateStringEscape) {
  386. stateStringEscape = false;
  387. } else {
  388. switch (chunk.charCodeAt(i)) {
  389. case 34:
  390. stateString = false;
  391. continue scan;
  392. case 92:
  393. stateStringEscape = true;
  394. }
  395. }
  396. }
  397. break;
  398. }
  399. switch (chunk.charCodeAt(i)) {
  400. case 34:
  401. stateString = true;
  402. stateStringEscape = false;
  403. seenNonWhiteSpace = true;
  404. break;
  405. case 44:
  406. flushPoint = i;
  407. break;
  408. case 123:
  409. flushPoint = i + 1;
  410. stack[flushDepth++] = STACK_OBJECT;
  411. seenNonWhiteSpace = true;
  412. break;
  413. case 91:
  414. flushPoint = i + 1;
  415. stack[flushDepth++] = STACK_ARRAY;
  416. seenNonWhiteSpace = true;
  417. break;
  418. case 93:
  419. /* ] */
  420. case 125:
  421. flushPoint = i + 1;
  422. if (flushDepth === 0) {
  423. break scan;
  424. }
  425. flushDepth--;
  426. if (flushDepth < lastFlushDepth) {
  427. flush(chunk, lastFlushPoint, flushPoint);
  428. lastFlushPoint = flushPoint;
  429. }
  430. break;
  431. case 9:
  432. /* \t */
  433. case 10:
  434. /* \n */
  435. case 13:
  436. /* \r */
  437. case 32:
  438. if (flushDepth === 0) {
  439. if (seenNonWhiteSpace) {
  440. flushPoint = i;
  441. flush(chunk, lastFlushPoint, flushPoint);
  442. lastFlushPoint = flushPoint;
  443. }
  444. if (parseMode !== MODE_JSON && allowNewRootValue === false && (chunk.charCodeAt(i) === 10 || chunk.charCodeAt(i) === 13)) {
  445. allowNewRootValue = true;
  446. }
  447. if (flushPoint === i) {
  448. parsedChunkLength++;
  449. }
  450. }
  451. if (lastFlushPoint === i) {
  452. lastFlushPoint++;
  453. }
  454. if (flushPoint === i) {
  455. flushPoint++;
  456. }
  457. break;
  458. default:
  459. seenNonWhiteSpace = true;
  460. }
  461. }
  462. if (flushPoint > lastFlushPoint) {
  463. flush(chunk, lastFlushPoint, flushPoint);
  464. }
  465. if (flushPoint < chunkLength) {
  466. if (pendingChunk !== null) {
  467. pendingChunk += chunk;
  468. } else {
  469. pendingChunk = chunk.slice(flushPoint, chunkLength);
  470. }
  471. }
  472. consumedChunkLength += chunkLength;
  473. if (typeof onChunk === "function") {
  474. onChunk(parsedChunkLength - prevParsedChunkLength, chunk, pendingChunk, state);
  475. }
  476. }
  477. function finish() {
  478. if (pendingChunk !== null || currentRootValue === NO_VALUE && parseMode !== MODE_JSONL) {
  479. flushDepth = 0;
  480. flush("", 0, 0);
  481. }
  482. if (typeof onChunk === "function") {
  483. parsedChunkLength = consumedChunkLength;
  484. onChunk(0, null, null, state);
  485. }
  486. if (typeof onRootValue === "function") {
  487. return rootValuesCount;
  488. }
  489. return rootValues !== null ? rootValues : currentRootValue;
  490. }
  491. }
  492. // src/stringify-chunked.js
  493. function encodeString(value) {
  494. if (/[^\x20\x21\x23-\x5B\x5D-\uD799]/.test(value)) {
  495. return JSON.stringify(value);
  496. }
  497. return '"' + value + '"';
  498. }
  499. function* stringifyChunked(value, ...args) {
  500. const { replacer, getKeys, space, ...options } = normalizeStringifyOptions(...args);
  501. const highWaterMark = Number(options.highWaterMark) || 16384;
  502. const roots = resolveStringifyMode(options.mode) === "jsonl" && Array.isArray(value) ? value : [value];
  503. const rootCount = roots.length;
  504. const keyStrings = /* @__PURE__ */ new Map();
  505. const stack = [];
  506. let rootValue = null;
  507. let prevState = null;
  508. let state = null;
  509. let stateValue = null;
  510. let stateEmpty = true;
  511. let stateKeys = [];
  512. let stateIndex = 0;
  513. let buffer = "";
  514. for (let i = 0; i < rootCount; i++) {
  515. if (rootValue !== null) {
  516. buffer += "\n";
  517. }
  518. rootValue = { "": roots[i] };
  519. prevState = null;
  520. state = () => printEntry("", roots[i]);
  521. stateValue = rootValue;
  522. stateEmpty = true;
  523. stateKeys = [""];
  524. stateIndex = 0;
  525. do {
  526. state();
  527. if (buffer.length >= highWaterMark || prevState === null && i === rootCount - 1) {
  528. yield buffer;
  529. buffer = "";
  530. }
  531. } while (prevState !== null);
  532. }
  533. function printObject() {
  534. if (stateIndex === 0) {
  535. stateKeys = getKeys(stateValue);
  536. buffer += "{";
  537. }
  538. if (stateIndex === stateKeys.length) {
  539. buffer += space && !stateEmpty ? `
  540. ${space.repeat(stack.length - 1)}}` : "}";
  541. popState();
  542. return;
  543. }
  544. const key = stateKeys[stateIndex++];
  545. printEntry(key, stateValue[key]);
  546. }
  547. function printArray() {
  548. if (stateIndex === 0) {
  549. buffer += "[";
  550. }
  551. if (stateIndex === stateValue.length) {
  552. buffer += space && !stateEmpty ? `
  553. ${space.repeat(stack.length - 1)}]` : "]";
  554. popState();
  555. return;
  556. }
  557. printEntry(stateIndex, stateValue[stateIndex++]);
  558. }
  559. function printEntryPrelude(key) {
  560. if (stateEmpty) {
  561. stateEmpty = false;
  562. } else {
  563. buffer += ",";
  564. }
  565. if (space && prevState !== null) {
  566. buffer += `
  567. ${space.repeat(stack.length)}`;
  568. }
  569. if (state === printObject) {
  570. let keyString = keyStrings.get(key);
  571. if (keyString === void 0) {
  572. keyStrings.set(key, keyString = encodeString(key) + (space ? ": " : ":"));
  573. }
  574. buffer += keyString;
  575. }
  576. }
  577. function printEntry(key, value2) {
  578. value2 = replaceValue(stateValue, key, value2, replacer);
  579. if (value2 === null || typeof value2 !== "object") {
  580. if (state !== printObject || value2 !== void 0) {
  581. printEntryPrelude(key);
  582. pushPrimitive(value2);
  583. }
  584. } else {
  585. if (stack.includes(value2)) {
  586. throw new TypeError("Converting circular structure to JSON");
  587. }
  588. printEntryPrelude(key);
  589. stack.push(value2);
  590. pushState();
  591. state = Array.isArray(value2) ? printArray : printObject;
  592. stateValue = value2;
  593. stateEmpty = true;
  594. stateIndex = 0;
  595. }
  596. }
  597. function pushPrimitive(value2) {
  598. switch (typeof value2) {
  599. case "string":
  600. buffer += encodeString(value2);
  601. break;
  602. case "number":
  603. buffer += Number.isFinite(value2) ? String(value2) : "null";
  604. break;
  605. case "boolean":
  606. buffer += value2 ? "true" : "false";
  607. break;
  608. case "undefined":
  609. case "object":
  610. buffer += "null";
  611. break;
  612. default:
  613. throw new TypeError(`Do not know how to serialize a ${value2.constructor?.name || typeof value2}`);
  614. }
  615. }
  616. function pushState() {
  617. prevState = {
  618. keys: stateKeys,
  619. index: stateIndex,
  620. prev: prevState
  621. };
  622. }
  623. function popState() {
  624. stack.pop();
  625. const value2 = stack.length > 0 ? stack[stack.length - 1] : rootValue;
  626. state = Array.isArray(value2) ? printArray : printObject;
  627. stateValue = value2;
  628. stateEmpty = false;
  629. stateKeys = prevState.keys;
  630. stateIndex = prevState.index;
  631. prevState = prevState.prev;
  632. }
  633. }
  634. // src/stringify-info.js
  635. var hasOwn = typeof Object.hasOwn === "function" ? Object.hasOwn : (object, key) => Object.hasOwnProperty.call(object, key);
  636. var escapableCharCodeSubstitution = {
  637. // JSON Single Character Escape Sequences
  638. 8: "\\b",
  639. 9: "\\t",
  640. 10: "\\n",
  641. 12: "\\f",
  642. 13: "\\r",
  643. 34: '\\"',
  644. 92: "\\\\"
  645. };
  646. var charLength2048 = Uint8Array.from({ length: 2048 }, (_, code) => {
  647. if (hasOwn(escapableCharCodeSubstitution, code)) {
  648. return 2;
  649. }
  650. if (code < 32) {
  651. return 6;
  652. }
  653. return code < 128 ? 1 : 2;
  654. });
  655. function isLeadingSurrogate(code) {
  656. return code >= 55296 && code <= 56319;
  657. }
  658. function isTrailingSurrogate(code) {
  659. return code >= 56320 && code <= 57343;
  660. }
  661. function stringLength(str) {
  662. if (!/[^\x20\x21\x23-\x5B\x5D-\x7F]/.test(str)) {
  663. return str.length + 2;
  664. }
  665. let len = 0;
  666. let prevLeadingSurrogate = false;
  667. for (let i = 0; i < str.length; i++) {
  668. const code = str.charCodeAt(i);
  669. if (code < 2048) {
  670. len += charLength2048[code];
  671. } else if (isLeadingSurrogate(code)) {
  672. len += 6;
  673. prevLeadingSurrogate = true;
  674. continue;
  675. } else if (isTrailingSurrogate(code)) {
  676. len = prevLeadingSurrogate ? len - 2 : len + 6;
  677. } else {
  678. len += 3;
  679. }
  680. prevLeadingSurrogate = false;
  681. }
  682. return len + 2;
  683. }
  684. function intLength(num) {
  685. let len = 0;
  686. if (num < 0) {
  687. len = 1;
  688. num = -num;
  689. }
  690. if (num >= 1e9) {
  691. len += 9;
  692. num = (num - num % 1e9) / 1e9;
  693. }
  694. if (num >= 1e4) {
  695. if (num >= 1e6) {
  696. return len + (num >= 1e8 ? 9 : num >= 1e7 ? 8 : 7);
  697. }
  698. return len + (num >= 1e5 ? 6 : 5);
  699. }
  700. return len + (num >= 100 ? num >= 1e3 ? 4 : 3 : num >= 10 ? 2 : 1);
  701. }
  702. function primitiveLength(value) {
  703. switch (typeof value) {
  704. case "string":
  705. return stringLength(value);
  706. case "number":
  707. return Number.isFinite(value) ? Number.isInteger(value) ? intLength(value) : String(value).length : 4;
  708. case "boolean":
  709. return value ? 4 : 5;
  710. case "undefined":
  711. case "object":
  712. return 4;
  713. /* null */
  714. default:
  715. return 0;
  716. }
  717. }
  718. function stringifyInfo(value, ...args) {
  719. const { replacer, getKeys, ...options } = normalizeStringifyOptions(...args);
  720. const continueOnCircular = Boolean(options.continueOnCircular);
  721. const space = options.space?.length || 0;
  722. const roots = resolveStringifyMode(options.mode) === "jsonl" && Array.isArray(value) ? value : [value];
  723. const keysLength = /* @__PURE__ */ new Map();
  724. const visited = /* @__PURE__ */ new Map();
  725. const circular = /* @__PURE__ */ new Set();
  726. const stack = [];
  727. let stop = false;
  728. let bytes = 0;
  729. let spaceBytes = 0;
  730. let objects = 0;
  731. for (let i = 0; i < roots.length; i++) {
  732. if (i > 0) {
  733. bytes += 1;
  734. }
  735. walk({ "": roots[i] }, "", roots[i]);
  736. }
  737. if (bytes === 0 && roots.length === 1) {
  738. bytes += 9;
  739. }
  740. return {
  741. bytes: isNaN(bytes) ? Infinity : bytes + spaceBytes,
  742. spaceBytes: space > 0 && isNaN(bytes) ? Infinity : spaceBytes,
  743. circular: [...circular]
  744. };
  745. function walk(holder, key, value2) {
  746. if (stop) {
  747. return;
  748. }
  749. value2 = replaceValue(holder, key, value2, replacer);
  750. if (value2 === null || typeof value2 !== "object") {
  751. if (value2 !== void 0 || Array.isArray(holder)) {
  752. bytes += primitiveLength(value2);
  753. }
  754. } else {
  755. if (stack.includes(value2)) {
  756. circular.add(value2);
  757. bytes += 4;
  758. if (!continueOnCircular) {
  759. stop = true;
  760. }
  761. return;
  762. }
  763. if (visited.has(value2)) {
  764. bytes += visited.get(value2);
  765. return;
  766. }
  767. objects++;
  768. const prevObjects = objects;
  769. const valueBytes = bytes;
  770. let valueLength = 0;
  771. stack.push(value2);
  772. if (Array.isArray(value2)) {
  773. valueLength = value2.length;
  774. for (let i = 0; i < valueLength; i++) {
  775. walk(value2, i, value2[i]);
  776. }
  777. } else {
  778. let prevLength = bytes;
  779. for (const key2 of getKeys(value2)) {
  780. walk(value2, key2, value2[key2]);
  781. if (prevLength !== bytes) {
  782. let keyLen = keysLength.get(key2);
  783. if (keyLen === void 0) {
  784. keysLength.set(key2, keyLen = stringLength(key2) + 1);
  785. }
  786. bytes += keyLen;
  787. valueLength++;
  788. prevLength = bytes;
  789. }
  790. }
  791. }
  792. bytes += valueLength === 0 ? 2 : 1 + valueLength;
  793. if (space > 0 && valueLength > 0) {
  794. spaceBytes += // a space between ":" and a value for each object entry
  795. (Array.isArray(value2) ? 0 : valueLength) + // the formula results from folding the following components:
  796. // - for each key-value or element: ident + newline
  797. // (1 + stack.length * space) * valueLength
  798. // - ident (one space less) before "}" or "]" + newline
  799. // (stack.length - 1) * space + 1
  800. (1 + stack.length * space) * (valueLength + 1) - space;
  801. }
  802. stack.pop();
  803. if (prevObjects !== objects) {
  804. visited.set(value2, bytes - valueBytes);
  805. }
  806. }
  807. }
  808. }
  809. // src/web-streams.js
  810. function parseFromWebStream(stream) {
  811. return parseChunked(isIterable(stream) ? stream : async function* () {
  812. const reader = stream.getReader();
  813. try {
  814. while (true) {
  815. const { value, done } = await reader.read();
  816. if (done) {
  817. break;
  818. }
  819. yield value;
  820. }
  821. } finally {
  822. reader.releaseLock();
  823. }
  824. });
  825. }
  826. function createStringifyWebStream(value, replacer, space) {
  827. if (typeof ReadableStream.from === "function") {
  828. return ReadableStream.from(stringifyChunked(value, replacer, space));
  829. }
  830. return new ReadableStream({
  831. start() {
  832. this.generator = stringifyChunked(value, replacer, space);
  833. },
  834. pull(controller) {
  835. const { value: value2, done } = this.generator.next();
  836. if (done) {
  837. controller.close();
  838. } else {
  839. controller.enqueue(value2);
  840. }
  841. },
  842. cancel() {
  843. this.generator = null;
  844. }
  845. });
  846. }
  847. return {
  848. createStringifyWebStream,
  849. parseChunked,
  850. parseFromWebStream,
  851. stringifyChunked,
  852. stringifyInfo
  853. };
  854. })));