UNPKG

@piadina/fetch-jsonl

Version:

Stream and parse (**JSON Lines**)[https://jsonlines.org/] directly with fetch. Yields parsed JSON objects one line at a time.

115 lines (114 loc) 3.1 kB
Object.defineProperty(exports, "__esModule", { value: true }); var LINE_SPLIT_REGEX = /\r\n|[\r\n]/g; var LinesTransformer = class { lastString = ""; decoder = new TextDecoder(); transform(chunk, controller) { const lines = `${this.lastString}${this.decoder.decode(chunk, { stream: true })}`.split(LINE_SPLIT_REGEX); this.lastString = lines.pop() || ""; lines.forEach((line) => { controller.enqueue(line); }); } flush(controller) { if (this.lastString) controller.enqueue(this.lastString); } }; var FetchJSONL = class { static instance; #fetchImpl; #reviver; hooks = { beforeRequest: [] }; constructor(options = {}) { this.#fetchImpl = options.fetchImpl ?? fetch; this.#reviver = options.reviver; this.hooks = { ...this.hooks, ...options?.hooks ?? {} }; } parseJSON(input) { return JSON.parse(input, this.#reviver); } async applyBeforeRequestHooks(request) { let req = request; for (const hook of this.hooks.beforeRequest ?? []) { const result = await hook(req); if (result instanceof Request) req = result; } return req; } async *stream(input, init) { let request = input instanceof Request ? input : new Request(input, init); request = await this.applyBeforeRequestHooks(request); const response = await this.#fetchImpl(request); if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`); if (!response.body) throw new Error("Response body is null"); const ts = new TransformStream(new LinesTransformer()); const reader = response.body.pipeThrough(ts).getReader(); try { while (true) { const { done, value } = await reader.read(); if (done) break; try { yield this.parseJSON(value); } catch (e) { throw e; } } } finally { reader.releaseLock(); } } #validateRequestMethod(input, expected) { if (input instanceof Request && input.method.toUpperCase() !== expected) throw new Error(`Request method mismatch: expected ${expected}, got ${input.method}`); } get(url, init) { this.#validateRequestMethod(url, "GET"); return this.stream(url, { ...init, method: "GET" }); } post(url, init) { this.#validateRequestMethod(url, "POST"); return this.stream(url, { ...init, method: "POST" }); } put(url, init) { this.#validateRequestMethod(url, "PUT"); return this.stream(url, { ...init, method: "PUT" }); } patch(url, init) { this.#validateRequestMethod(url, "PATCH"); return this.stream(url, { ...init, method: "PATCH" }); } delete(url, init) { this.#validateRequestMethod(url, "DELETE"); return this.stream(url, { ...init, method: "DELETE" }); } }; const createInstance = (defaults = {}) => { return new FetchJSONL(defaults); }; var fetchJSONL = createInstance(); var fetch_json_lines_default = fetchJSONL; var src_default = fetch_json_lines_default; const version = "0.0.1"; exports.FetchJSONL = FetchJSONL; exports.LinesTransformer = LinesTransformer; exports.createInstance = createInstance; exports.default = src_default; exports.version = version; //# sourceMappingURL=index.umd.debug.cjs.map