UNPKG

@worker-tools/json-stream

Version:

Utilities for working with streaming JSON in Worker Runtimes such as Cloudflare Workers, Deno Deploy and Service Workers.

114 lines 5.52 kB
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; // deno-lint-ignore-file no-explicit-any no-cond-assign ban-unused-ignore no-unused-vars import { streamToAsyncIter } from 'whatwg-stream-to-async-iter'; import { JSONParser } from './json-parser.js'; import { TaskPromise } from './task-promise.js'; import { normalize, match } from './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 normalize(path.join('.')); // FIXME: avoid string concatenation/joining }; export class JSONParseStream extends TransformStream { constructor(jsonPath = '$.*') { let parser; const expr = normalize(jsonPath); super({ start: (controller) => { parser = new JSONParser(); parser.onValue = (value) => { const path = mkPath(parser); if (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"); } } _JSONParseStream_jsonPath = new WeakMap(); const remove = (m, k) => { const v = m.get(k); m.delete(k); return v; }; /** @deprecated Rename!!! */ export class JSONParseNexus extends TransformStream { constructor() { let parser; super({ start: (controller) => { parser = new JSONParser(); parser.onValue = (value) => { const path = mkPath(parser); for (const expr of __classPrivateFieldGet(this, _JSONParseNexus_queues, "f").keys()) { if (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 TaskPromise.from(async () => { const x = await reader.read(); return x.done ? undefined : x.value; }); } stream(jsonPath) { const path = 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 || 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 streamToAsyncIter(this.stream(jsonPath)); } } _JSONParseNexus_queues = new WeakMap(), _JSONParseNexus_reader = new WeakMap(); //# sourceMappingURL=json-parse-stream.js.map