@worker-tools/json-stream
Version:
Utilities for working with streaming JSON in Worker Runtimes such as Cloudflare Workers, Deno Deploy and Service Workers.
119 lines • 5.96 kB
JavaScript
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _JSONParseStream_jsonPath, _JSONParseNexus_queues, _JSONParseNexus_reader;
Object.defineProperty(exports, "__esModule", { value: true });
exports.JSONParseNexus = exports.JSONParseStream = void 0;
// deno-lint-ignore-file no-explicit-any no-cond-assign ban-unused-ignore no-unused-vars
const whatwg_stream_to_async_iter_1 = require("whatwg-stream-to-async-iter");
const json_parser_js_1 = require("./json-parser.js");
const task_promise_js_1 = require("./task-promise.js");
const json_path_js_1 = require("./json-path.js");
// FIXME: avoid string concatenation/joining
const mkPath = (parser) => {
const path = [...parser.stack.map((_) => _.key), parser.key]; // TODO: modify parser to provide key efficiently
path[0] = path[0] || '$';
return (0, json_path_js_1.normalize)(path.join('.')); // FIXME: avoid string concatenation/joining
};
class JSONParseStream extends TransformStream {
constructor(jsonPath = '$.*') {
let parser;
const expr = (0, json_path_js_1.normalize)(jsonPath);
super({
start: (controller) => {
parser = new json_parser_js_1.JSONParser();
parser.onValue = (value) => {
const path = mkPath(parser);
if ((0, json_path_js_1.match)(expr, path)) {
controller.enqueue(value);
}
else if (expr.startsWith(path + ';')) {
controller.terminate();
}
};
},
transform: (chunk) => {
parser.write(chunk);
},
});
_JSONParseStream_jsonPath.set(this, void 0);
__classPrivateFieldSet(this, _JSONParseStream_jsonPath, expr, "f");
}
get path() { return __classPrivateFieldGet(this, _JSONParseStream_jsonPath, "f"); }
}
exports.JSONParseStream = JSONParseStream;
_JSONParseStream_jsonPath = new WeakMap();
const remove = (m, k) => { const v = m.get(k); m.delete(k); return v; };
/** @deprecated Rename!!! */
class JSONParseNexus extends TransformStream {
constructor() {
let parser;
super({
start: (controller) => {
parser = new json_parser_js_1.JSONParser();
parser.onValue = (value) => {
const path = mkPath(parser);
for (const expr of __classPrivateFieldGet(this, _JSONParseNexus_queues, "f").keys()) {
if ((0, json_path_js_1.match)(expr, path)) {
__classPrivateFieldGet(this, _JSONParseNexus_queues, "f").get(expr).enqueue(value);
} // no else if => can both be true
if (expr.startsWith(path + ';')) {
remove(__classPrivateFieldGet(this, _JSONParseNexus_queues, "f"), expr).close();
}
}
controller.enqueue([path, value]);
};
},
transform(buffer) {
// console.log('transform', buffer, controller.desiredSize)
parser.write(buffer);
},
});
_JSONParseNexus_queues.set(this, new Map());
_JSONParseNexus_reader.set(this, void 0);
__classPrivateFieldSet(this, _JSONParseNexus_reader, this.readable.getReader(), "f");
}
promise(jsonPath) {
const reader = this.stream(jsonPath).getReader();
return task_promise_js_1.TaskPromise.from(async () => {
const x = await reader.read();
return x.done ? undefined : x.value;
});
}
stream(jsonPath) {
const path = (0, json_path_js_1.normalize)(jsonPath);
return new ReadableStream({
start: (queue) => {
__classPrivateFieldGet(this, _JSONParseNexus_queues, "f").set(path, queue);
},
pull: async () => {
while (true) {
const { done, value } = await __classPrivateFieldGet(this, _JSONParseNexus_reader, "f").read();
// FIXME: avoid duplicate match
if (done || (0, json_path_js_1.match)(value[0], path))
break;
}
},
cancel: (err) => {
// If one of the child streams errors, error the whole pipeline.
// TODO: Or should it?
__classPrivateFieldGet(this, _JSONParseNexus_reader, "f").cancel(err);
},
}, { highWaterMark: 0 }); // does not pull on its own
}
iterable(jsonPath) {
return (0, whatwg_stream_to_async_iter_1.streamToAsyncIter)(this.stream(jsonPath));
}
}
exports.JSONParseNexus = JSONParseNexus;
_JSONParseNexus_queues = new WeakMap(), _JSONParseNexus_reader = new WeakMap();
//# sourceMappingURL=json-parse-stream.js.map
;