UNPKG

4.46 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.JSONStringifyReadable = exports.jsonStringifyStream = exports.jsonStringifyGenerator = exports.isAsyncIterable = exports.isIterable = void 0;
4// deno-lint-ignore-file no-explicit-any no-empty
5const whatwg_stream_to_async_iter_1 = require("whatwg-stream-to-async-iter");
6const isIterable = (x) => x != null && typeof x === 'object' && Symbol.iterator in x;
7exports.isIterable = isIterable;
8const isAsyncIterable = (x) => x != null && typeof x === 'object' && Symbol.asyncIterator in x;
9exports.isAsyncIterable = isAsyncIterable;
10const isPromiseLike = (x) => x != null && typeof x === 'object' && 'then' in x && typeof x.then === 'function';
11const isToJSON = (x) => x != null && typeof x === 'object' && 'toJSON' in x;
12const safeAdd = (seen, value) => {
13 if (seen.has(value))
14 throw TypeError('Converting circular structure to JSON');
15 seen.add(value);
16};
17const check = (v) => {
18 if (v === undefined)
19 return false;
20 const type = typeof v;
21 return type !== 'function' && type !== 'symbol';
22};
23// TODO: Add replacer
24// TODO: add formatting/spaces
25// TODO: concurrent objects/arrays
26/**
27 * @deprecated Change name to something more descriptive!?
28 */
29async function* jsonStringifyGenerator(value, seen = new WeakSet()) {
30 if ((0, exports.isAsyncIterable)(value)) {
31 yield '[';
32 safeAdd(seen, value);
33 let first = true;
34 for await (const v of value) {
35 if (!first)
36 yield ',';
37 else
38 first = false;
39 yield* jsonStringifyGenerator(v, seen);
40 }
41 seen.delete(value);
42 yield ']';
43 }
44 else if (isPromiseLike(value)) {
45 const v = await value;
46 if (check(v)) {
47 safeAdd(seen, value);
48 yield* jsonStringifyGenerator(v, seen);
49 seen.delete(value);
50 }
51 }
52 else if (isToJSON(value)) {
53 const v = JSON.stringify(value);
54 if (check(v))
55 yield v;
56 }
57 else if (Array.isArray(value)) {
58 yield '[';
59 safeAdd(seen, value);
60 let first = true;
61 for (const v of value) {
62 if (!first)
63 yield ',';
64 else
65 first = false;
66 yield* jsonStringifyGenerator(v, seen);
67 }
68 seen.delete(value);
69 yield ']';
70 }
71 else if (value != null && typeof value === 'object') {
72 yield '{';
73 safeAdd(seen, value);
74 let first = true;
75 for (const [k, v] of Object.entries(value)) {
76 if (check(v)) {
77 const generator = jsonStringifyGenerator(v, seen);
78 const peek = await generator.next();
79 if (check(peek.value)) {
80 if (!first)
81 yield ',';
82 else
83 first = false;
84 yield `${JSON.stringify(k)}:`;
85 yield peek.value;
86 yield* generator;
87 }
88 }
89 }
90 seen.delete(value);
91 yield '}';
92 }
93 else {
94 yield check(value) ? JSON.stringify(value) : 'null';
95 }
96}
97exports.jsonStringifyGenerator = jsonStringifyGenerator;
98/**
99 * @deprecated Change name to something more descriptive!?
100 */
101function jsonStringifyStream(value) {
102 return (0, whatwg_stream_to_async_iter_1.asyncIterToStream)(jsonStringifyGenerator(value));
103}
104exports.jsonStringifyStream = jsonStringifyStream;
105class JSONStringifyReadable extends ReadableStream {
106 constructor(value) {
107 let iterator;
108 super({
109 start() {
110 iterator = jsonStringifyGenerator(value)[Symbol.asyncIterator]();
111 },
112 async pull(controller) {
113 // console.log('stringify', controller.desiredSize)
114 const { value, done } = await iterator.next();
115 if (!done)
116 controller.enqueue(value);
117 else
118 controller.close();
119 },
120 async cancel(reason) {
121 var _a;
122 try {
123 await ((_a = iterator.throw) === null || _a === void 0 ? void 0 : _a.call(iterator, reason));
124 }
125 catch { }
126 },
127 });
128 }
129}
130exports.JSONStringifyReadable = JSONStringifyReadable;
131//# sourceMappingURL=json-stringify.js.map
\No newline at end of file