json-ext.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866
  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 returnValue() {
  194. return typeof onRootValue === "function" ? rootValuesCount : rootValues !== null ? rootValues : currentRootValue !== NO_VALUE ? currentRootValue : void 0;
  195. },
  196. get currentRootValue() {
  197. return currentRootValue !== NO_VALUE ? currentRootValue : void 0;
  198. },
  199. get rootValuesCount() {
  200. return rootValuesCount;
  201. },
  202. get consumed() {
  203. return consumedChunkLength;
  204. },
  205. get parsed() {
  206. return parsedChunkLength;
  207. }
  208. });
  209. return {
  210. push,
  211. finish,
  212. state,
  213. get jsonParseOffset() {
  214. return jsonParseOffset;
  215. }
  216. };
  217. function startRootValue(fragment) {
  218. if (!allowNewRootValue) {
  219. jsonParseOffset -= 2;
  220. JSON.parse("[]" + fragment);
  221. }
  222. if (currentRootValue !== NO_VALUE && parseMode === MODE_JSONL_AUTO) {
  223. parseMode = MODE_JSONL;
  224. rootValues = [currentRootValue];
  225. }
  226. allowNewRootValue = false;
  227. currentRootValue = JSON.parse(fragment);
  228. }
  229. function finishRootValue() {
  230. rootValuesCount++;
  231. if (typeof reviver === "function") {
  232. currentRootValue = applyReviver(currentRootValue, reviver);
  233. }
  234. if (typeof onRootValue === "function") {
  235. onRootValue(currentRootValue, state);
  236. } else if (parseMode === MODE_JSONL) {
  237. rootValues.push(currentRootValue);
  238. }
  239. }
  240. function mergeArraySlices() {
  241. if (prevArray === null) {
  242. return;
  243. }
  244. if (prevArraySlices.length !== 0) {
  245. const newArray = prevArraySlices.length === 1 ? prevArray.concat(prevArraySlices[0]) : prevArray.concat(...prevArraySlices);
  246. if (currentRootValueCursor.prev !== null) {
  247. currentRootValueCursor.prev.value[currentRootValueCursor.key] = newArray;
  248. } else {
  249. currentRootValue = newArray;
  250. }
  251. currentRootValueCursor.value = newArray;
  252. prevArraySlices = [];
  253. }
  254. prevArray = null;
  255. }
  256. function parseAndAppend(fragment, wrap) {
  257. if (stack[lastFlushDepth - 1] === STACK_OBJECT) {
  258. if (wrap) {
  259. jsonParseOffset--;
  260. fragment = "{" + fragment + "}";
  261. }
  262. Object.assign(currentRootValueCursor.value, JSON.parse(fragment));
  263. } else {
  264. if (wrap) {
  265. jsonParseOffset--;
  266. fragment = "[" + fragment + "]";
  267. }
  268. if (prevArray === currentRootValueCursor.value) {
  269. prevArraySlices.push(JSON.parse(fragment));
  270. } else {
  271. append(currentRootValueCursor.value, JSON.parse(fragment));
  272. prevArray = currentRootValueCursor.value;
  273. }
  274. }
  275. }
  276. function prepareAddition(fragment) {
  277. const { value } = currentRootValueCursor;
  278. const expectComma = Array.isArray(value) ? value.length !== 0 : Object.keys(value).length !== 0;
  279. if (expectComma) {
  280. if (fragment[0] === ",") {
  281. jsonParseOffset++;
  282. return fragment.slice(1);
  283. }
  284. if (fragment[0] !== "}" && fragment[0] !== "]") {
  285. jsonParseOffset -= 3;
  286. return "[[]" + fragment;
  287. }
  288. }
  289. return fragment;
  290. }
  291. function flush(chunk, start, end) {
  292. let fragment = chunk.slice(start, end);
  293. jsonParseOffset = consumedChunkLength + start;
  294. parsedChunkLength += end - start;
  295. if (pendingChunk !== null) {
  296. fragment = pendingChunk + fragment;
  297. jsonParseOffset -= pendingChunk.length;
  298. parsedChunkLength += pendingChunk.length;
  299. pendingChunk = null;
  300. }
  301. if (flushDepth === lastFlushDepth) {
  302. if (lastFlushDepth === 0) {
  303. startRootValue(fragment);
  304. } else {
  305. parseAndAppend(prepareAddition(fragment), true);
  306. }
  307. } else if (flushDepth > lastFlushDepth) {
  308. for (let i = flushDepth - 1; i >= lastFlushDepth; i--) {
  309. fragment += stack[i] === STACK_OBJECT ? "}" : "]";
  310. }
  311. if (lastFlushDepth === 0) {
  312. startRootValue(fragment);
  313. currentRootValueCursor = {
  314. value: currentRootValue,
  315. key: null,
  316. prev: null
  317. };
  318. } else {
  319. parseAndAppend(prepareAddition(fragment), true);
  320. mergeArraySlices();
  321. }
  322. for (let i = lastFlushDepth || 1; i < flushDepth; i++) {
  323. let { value } = currentRootValueCursor;
  324. let key = null;
  325. if (stack[i - 1] === STACK_OBJECT) {
  326. for (key in value) ;
  327. value = value[key];
  328. } else {
  329. key = value.length - 1;
  330. value = value[key];
  331. }
  332. currentRootValueCursor = {
  333. value,
  334. key,
  335. prev: currentRootValueCursor
  336. };
  337. }
  338. } else {
  339. fragment = prepareAddition(fragment);
  340. for (let i = lastFlushDepth - 1; i >= flushDepth; i--) {
  341. jsonParseOffset--;
  342. fragment = (stack[i] === STACK_OBJECT ? "{" : "[") + fragment;
  343. }
  344. parseAndAppend(fragment, false);
  345. mergeArraySlices();
  346. for (let i = lastFlushDepth - 1; i >= flushDepth; i--) {
  347. currentRootValueCursor = currentRootValueCursor.prev;
  348. }
  349. }
  350. if (flushDepth === 0) {
  351. finishRootValue();
  352. }
  353. lastFlushDepth = flushDepth;
  354. seenNonWhiteSpace = false;
  355. }
  356. function ensureChunkString(chunk) {
  357. if (typeof chunk !== "string") {
  358. if (pendingByteSeq !== null) {
  359. const origRawChunk = chunk;
  360. chunk = new Uint8Array(pendingByteSeq.length + origRawChunk.length);
  361. chunk.set(pendingByteSeq);
  362. chunk.set(origRawChunk, pendingByteSeq.length);
  363. pendingByteSeq = null;
  364. }
  365. if (chunk[chunk.length - 1] > 127) {
  366. for (let seqLength = 0; seqLength < chunk.length; seqLength++) {
  367. const byte = chunk[chunk.length - 1 - seqLength];
  368. if (byte >> 6 === 3) {
  369. seqLength++;
  370. if (seqLength !== 4 && byte >> 3 === 30 || seqLength !== 3 && byte >> 4 === 14 || seqLength !== 2 && byte >> 5 === 6) {
  371. pendingByteSeq = chunk.slice(chunk.length - seqLength);
  372. chunk = chunk.subarray(0, -seqLength);
  373. }
  374. break;
  375. }
  376. }
  377. }
  378. chunk = decoder.decode(chunk);
  379. }
  380. return chunk;
  381. }
  382. function push(chunk) {
  383. chunk = ensureChunkString(chunk);
  384. const chunkLength = chunk.length;
  385. const prevParsedChunkLength = parsedChunkLength;
  386. let lastFlushPoint = 0;
  387. let flushPoint = 0;
  388. scan: for (let i = 0; i < chunkLength; i++) {
  389. if (stateString) {
  390. for (; i < chunkLength; i++) {
  391. if (stateStringEscape) {
  392. stateStringEscape = false;
  393. } else {
  394. switch (chunk.charCodeAt(i)) {
  395. case 34:
  396. stateString = false;
  397. continue scan;
  398. case 92:
  399. stateStringEscape = true;
  400. }
  401. }
  402. }
  403. break;
  404. }
  405. switch (chunk.charCodeAt(i)) {
  406. case 34:
  407. stateString = true;
  408. stateStringEscape = false;
  409. seenNonWhiteSpace = true;
  410. break;
  411. case 44:
  412. flushPoint = i;
  413. break;
  414. case 123:
  415. flushPoint = i + 1;
  416. stack[flushDepth++] = STACK_OBJECT;
  417. seenNonWhiteSpace = true;
  418. break;
  419. case 91:
  420. flushPoint = i + 1;
  421. stack[flushDepth++] = STACK_ARRAY;
  422. seenNonWhiteSpace = true;
  423. break;
  424. case 93:
  425. /* ] */
  426. case 125:
  427. flushPoint = i + 1;
  428. if (flushDepth === 0) {
  429. break scan;
  430. }
  431. flushDepth--;
  432. if (flushDepth < lastFlushDepth) {
  433. flush(chunk, lastFlushPoint, flushPoint);
  434. lastFlushPoint = flushPoint;
  435. }
  436. break;
  437. case 9:
  438. /* \t */
  439. case 10:
  440. /* \n */
  441. case 13:
  442. /* \r */
  443. case 32:
  444. if (flushDepth === 0) {
  445. if (seenNonWhiteSpace) {
  446. flushPoint = i;
  447. flush(chunk, lastFlushPoint, flushPoint);
  448. lastFlushPoint = flushPoint;
  449. }
  450. if (parseMode !== MODE_JSON && allowNewRootValue === false && (chunk.charCodeAt(i) === 10 || chunk.charCodeAt(i) === 13)) {
  451. allowNewRootValue = true;
  452. }
  453. if (flushPoint === i) {
  454. parsedChunkLength++;
  455. }
  456. }
  457. if (lastFlushPoint === i) {
  458. lastFlushPoint++;
  459. }
  460. if (flushPoint === i) {
  461. flushPoint++;
  462. }
  463. break;
  464. default:
  465. seenNonWhiteSpace = true;
  466. }
  467. }
  468. if (flushPoint > lastFlushPoint) {
  469. flush(chunk, lastFlushPoint, flushPoint);
  470. }
  471. if (flushPoint < chunkLength) {
  472. if (pendingChunk !== null) {
  473. pendingChunk += chunk;
  474. } else {
  475. pendingChunk = chunk.slice(flushPoint, chunkLength);
  476. }
  477. }
  478. consumedChunkLength += chunkLength;
  479. if (typeof onChunk === "function") {
  480. onChunk(parsedChunkLength - prevParsedChunkLength, chunk, pendingChunk, state);
  481. }
  482. }
  483. function finish() {
  484. if (pendingChunk !== null || currentRootValue === NO_VALUE && parseMode !== MODE_JSONL) {
  485. flushDepth = 0;
  486. flush("", 0, 0);
  487. }
  488. if (typeof onChunk === "function") {
  489. parsedChunkLength = consumedChunkLength;
  490. onChunk(0, null, null, state);
  491. }
  492. const result = state.returnValue;
  493. rootValues = null;
  494. currentRootValue = NO_VALUE;
  495. return result;
  496. }
  497. }
  498. // src/stringify-chunked.js
  499. function encodeString(value) {
  500. if (/[^\x20\x21\x23-\x5B\x5D-\uD799]/.test(value)) {
  501. return JSON.stringify(value);
  502. }
  503. return '"' + value + '"';
  504. }
  505. function* stringifyChunked(value, ...args) {
  506. const { replacer, getKeys, space, ...options } = normalizeStringifyOptions(...args);
  507. const highWaterMark = Number(options.highWaterMark) || 16384;
  508. const roots = resolveStringifyMode(options.mode) === "jsonl" && Array.isArray(value) ? value : [value];
  509. const rootCount = roots.length;
  510. const keyStrings = /* @__PURE__ */ new Map();
  511. const stack = [];
  512. let rootValue = null;
  513. let prevState = null;
  514. let state = null;
  515. let stateValue = null;
  516. let stateEmpty = true;
  517. let stateKeys = [];
  518. let stateIndex = 0;
  519. let buffer = "";
  520. for (let i = 0; i < rootCount; i++) {
  521. if (rootValue !== null) {
  522. buffer += "\n";
  523. }
  524. rootValue = { "": roots[i] };
  525. prevState = null;
  526. state = () => printEntry("", roots[i]);
  527. stateValue = rootValue;
  528. stateEmpty = true;
  529. stateKeys = [""];
  530. stateIndex = 0;
  531. do {
  532. state();
  533. if (buffer.length >= highWaterMark || prevState === null && i === rootCount - 1) {
  534. yield buffer;
  535. buffer = "";
  536. }
  537. } while (prevState !== null);
  538. }
  539. function printObject() {
  540. if (stateIndex === 0) {
  541. stateKeys = getKeys(stateValue);
  542. buffer += "{";
  543. }
  544. if (stateIndex === stateKeys.length) {
  545. buffer += space && !stateEmpty ? `
  546. ${space.repeat(stack.length - 1)}}` : "}";
  547. popState();
  548. return;
  549. }
  550. const key = stateKeys[stateIndex++];
  551. printEntry(key, stateValue[key]);
  552. }
  553. function printArray() {
  554. if (stateIndex === 0) {
  555. buffer += "[";
  556. }
  557. if (stateIndex === stateValue.length) {
  558. buffer += space && !stateEmpty ? `
  559. ${space.repeat(stack.length - 1)}]` : "]";
  560. popState();
  561. return;
  562. }
  563. printEntry(stateIndex, stateValue[stateIndex++]);
  564. }
  565. function printEntryPrelude(key) {
  566. if (stateEmpty) {
  567. stateEmpty = false;
  568. } else {
  569. buffer += ",";
  570. }
  571. if (space && prevState !== null) {
  572. buffer += `
  573. ${space.repeat(stack.length)}`;
  574. }
  575. if (state === printObject) {
  576. let keyString = keyStrings.get(key);
  577. if (keyString === void 0) {
  578. keyStrings.set(key, keyString = encodeString(key) + (space ? ": " : ":"));
  579. }
  580. buffer += keyString;
  581. }
  582. }
  583. function printEntry(key, value2) {
  584. value2 = replaceValue(stateValue, key, value2, replacer);
  585. if (value2 === null || typeof value2 !== "object") {
  586. if (state !== printObject || value2 !== void 0) {
  587. printEntryPrelude(key);
  588. pushPrimitive(value2);
  589. }
  590. } else {
  591. if (stack.includes(value2)) {
  592. throw new TypeError("Converting circular structure to JSON");
  593. }
  594. printEntryPrelude(key);
  595. stack.push(value2);
  596. pushState();
  597. state = Array.isArray(value2) ? printArray : printObject;
  598. stateValue = value2;
  599. stateEmpty = true;
  600. stateIndex = 0;
  601. }
  602. }
  603. function pushPrimitive(value2) {
  604. switch (typeof value2) {
  605. case "string":
  606. buffer += encodeString(value2);
  607. break;
  608. case "number":
  609. buffer += Number.isFinite(value2) ? String(value2) : "null";
  610. break;
  611. case "boolean":
  612. buffer += value2 ? "true" : "false";
  613. break;
  614. case "undefined":
  615. case "object":
  616. buffer += "null";
  617. break;
  618. default:
  619. throw new TypeError(`Do not know how to serialize a ${value2.constructor?.name || typeof value2}`);
  620. }
  621. }
  622. function pushState() {
  623. prevState = {
  624. keys: stateKeys,
  625. index: stateIndex,
  626. prev: prevState
  627. };
  628. }
  629. function popState() {
  630. stack.pop();
  631. const value2 = stack.length > 0 ? stack[stack.length - 1] : rootValue;
  632. state = Array.isArray(value2) ? printArray : printObject;
  633. stateValue = value2;
  634. stateEmpty = false;
  635. stateKeys = prevState.keys;
  636. stateIndex = prevState.index;
  637. prevState = prevState.prev;
  638. }
  639. }
  640. // src/stringify-info.js
  641. var hasOwn = typeof Object.hasOwn === "function" ? Object.hasOwn : (object, key) => Object.hasOwnProperty.call(object, key);
  642. var escapableCharCodeSubstitution = {
  643. // JSON Single Character Escape Sequences
  644. 8: "\\b",
  645. 9: "\\t",
  646. 10: "\\n",
  647. 12: "\\f",
  648. 13: "\\r",
  649. 34: '\\"',
  650. 92: "\\\\"
  651. };
  652. var charLength2048 = Uint8Array.from({ length: 2048 }, (_, code) => {
  653. if (hasOwn(escapableCharCodeSubstitution, code)) {
  654. return 2;
  655. }
  656. if (code < 32) {
  657. return 6;
  658. }
  659. return code < 128 ? 1 : 2;
  660. });
  661. function isLeadingSurrogate(code) {
  662. return code >= 55296 && code <= 56319;
  663. }
  664. function isTrailingSurrogate(code) {
  665. return code >= 56320 && code <= 57343;
  666. }
  667. function stringLength(str) {
  668. if (!/[^\x20\x21\x23-\x5B\x5D-\x7F]/.test(str)) {
  669. return str.length + 2;
  670. }
  671. let len = 0;
  672. let prevLeadingSurrogate = false;
  673. for (let i = 0; i < str.length; i++) {
  674. const code = str.charCodeAt(i);
  675. if (code < 2048) {
  676. len += charLength2048[code];
  677. } else if (isLeadingSurrogate(code)) {
  678. len += 6;
  679. prevLeadingSurrogate = true;
  680. continue;
  681. } else if (isTrailingSurrogate(code)) {
  682. len = prevLeadingSurrogate ? len - 2 : len + 6;
  683. } else {
  684. len += 3;
  685. }
  686. prevLeadingSurrogate = false;
  687. }
  688. return len + 2;
  689. }
  690. function intLength(num) {
  691. let len = 0;
  692. if (num < 0) {
  693. len = 1;
  694. num = -num;
  695. }
  696. if (num >= 1e9) {
  697. len += 9;
  698. num = (num - num % 1e9) / 1e9;
  699. }
  700. if (num >= 1e4) {
  701. if (num >= 1e6) {
  702. return len + (num >= 1e8 ? 9 : num >= 1e7 ? 8 : 7);
  703. }
  704. return len + (num >= 1e5 ? 6 : 5);
  705. }
  706. return len + (num >= 100 ? num >= 1e3 ? 4 : 3 : num >= 10 ? 2 : 1);
  707. }
  708. function primitiveLength(value) {
  709. switch (typeof value) {
  710. case "string":
  711. return stringLength(value);
  712. case "number":
  713. return Number.isFinite(value) ? Number.isInteger(value) ? intLength(value) : String(value).length : 4;
  714. case "boolean":
  715. return value ? 4 : 5;
  716. case "undefined":
  717. case "object":
  718. return 4;
  719. /* null */
  720. default:
  721. return 0;
  722. }
  723. }
  724. function stringifyInfo(value, ...args) {
  725. const { replacer, getKeys, ...options } = normalizeStringifyOptions(...args);
  726. const continueOnCircular = Boolean(options.continueOnCircular);
  727. const space = options.space?.length || 0;
  728. const roots = resolveStringifyMode(options.mode) === "jsonl" && Array.isArray(value) ? value : [value];
  729. const keysLength = /* @__PURE__ */ new Map();
  730. const visited = /* @__PURE__ */ new Map();
  731. const circular = /* @__PURE__ */ new Set();
  732. const stack = [];
  733. let stop = false;
  734. let bytes = 0;
  735. let spaceBytes = 0;
  736. let objects = 0;
  737. for (let i = 0; i < roots.length; i++) {
  738. if (i > 0) {
  739. bytes += 1;
  740. }
  741. walk({ "": roots[i] }, "", roots[i]);
  742. }
  743. if (bytes === 0 && roots.length === 1) {
  744. bytes += 9;
  745. }
  746. return {
  747. bytes: isNaN(bytes) ? Infinity : bytes + spaceBytes,
  748. spaceBytes: space > 0 && isNaN(bytes) ? Infinity : spaceBytes,
  749. circular: [...circular]
  750. };
  751. function walk(holder, key, value2) {
  752. if (stop) {
  753. return;
  754. }
  755. value2 = replaceValue(holder, key, value2, replacer);
  756. if (value2 === null || typeof value2 !== "object") {
  757. if (value2 !== void 0 || Array.isArray(holder)) {
  758. bytes += primitiveLength(value2);
  759. }
  760. } else {
  761. if (stack.includes(value2)) {
  762. circular.add(value2);
  763. bytes += 4;
  764. if (!continueOnCircular) {
  765. stop = true;
  766. }
  767. return;
  768. }
  769. if (visited.has(value2)) {
  770. bytes += visited.get(value2);
  771. return;
  772. }
  773. objects++;
  774. const prevObjects = objects;
  775. const valueBytes = bytes;
  776. let valueLength = 0;
  777. stack.push(value2);
  778. if (Array.isArray(value2)) {
  779. valueLength = value2.length;
  780. for (let i = 0; i < valueLength; i++) {
  781. walk(value2, i, value2[i]);
  782. }
  783. } else {
  784. let prevLength = bytes;
  785. for (const key2 of getKeys(value2)) {
  786. walk(value2, key2, value2[key2]);
  787. if (prevLength !== bytes) {
  788. let keyLen = keysLength.get(key2);
  789. if (keyLen === void 0) {
  790. keysLength.set(key2, keyLen = stringLength(key2) + 1);
  791. }
  792. bytes += keyLen;
  793. valueLength++;
  794. prevLength = bytes;
  795. }
  796. }
  797. }
  798. bytes += valueLength === 0 ? 2 : 1 + valueLength;
  799. if (space > 0 && valueLength > 0) {
  800. spaceBytes += // a space between ":" and a value for each object entry
  801. (Array.isArray(value2) ? 0 : valueLength) + // the formula results from folding the following components:
  802. // - for each key-value or element: ident + newline
  803. // (1 + stack.length * space) * valueLength
  804. // - ident (one space less) before "}" or "]" + newline
  805. // (stack.length - 1) * space + 1
  806. (1 + stack.length * space) * (valueLength + 1) - space;
  807. }
  808. stack.pop();
  809. if (prevObjects !== objects) {
  810. visited.set(value2, bytes - valueBytes);
  811. }
  812. }
  813. }
  814. }
  815. // src/web-streams.js
  816. function parseFromWebStream(stream) {
  817. return parseChunked(isIterable(stream) ? stream : async function* () {
  818. const reader = stream.getReader();
  819. try {
  820. while (true) {
  821. const { value, done } = await reader.read();
  822. if (done) {
  823. break;
  824. }
  825. yield value;
  826. }
  827. } finally {
  828. reader.releaseLock();
  829. }
  830. });
  831. }
  832. function createStringifyWebStream(value, replacer, space) {
  833. if (typeof ReadableStream.from === "function") {
  834. return ReadableStream.from(stringifyChunked(value, replacer, space));
  835. }
  836. return new ReadableStream({
  837. start() {
  838. this.generator = stringifyChunked(value, replacer, space);
  839. },
  840. pull(controller) {
  841. const { value: value2, done } = this.generator.next();
  842. if (done) {
  843. controller.close();
  844. } else {
  845. controller.enqueue(value2);
  846. }
  847. },
  848. cancel() {
  849. this.generator = null;
  850. }
  851. });
  852. }
  853. return {
  854. createStringifyWebStream,
  855. parseChunked,
  856. parseFromWebStream,
  857. stringifyChunked,
  858. stringifyInfo
  859. };
  860. })));