UNPKG

blade

Version:
162 lines (158 loc) 4.62 kB
import { n as resolveCallback, t as HtmlEscapedCallbackPhase } from "./html-BHm7adlz.js"; //#region ../../node_modules/hono/dist/utils/stream.js var StreamingApi = class { writer; encoder; writable; abortSubscribers = []; responseReadable; aborted = false; closed = false; constructor(writable, _readable) { this.writable = writable; this.writer = writable.getWriter(); this.encoder = new TextEncoder(); const reader = _readable.getReader(); this.abortSubscribers.push(async () => { await reader.cancel(); }); this.responseReadable = new ReadableStream({ async pull(controller) { const { done, value } = await reader.read(); done ? controller.close() : controller.enqueue(value); }, cancel: () => { this.abort(); } }); } async write(input) { try { if (typeof input === "string") input = this.encoder.encode(input); await this.writer.write(input); } catch {} return this; } async writeln(input) { await this.write(input + "\n"); return this; } sleep(ms) { return new Promise((res) => setTimeout(res, ms)); } async close() { try { await this.writer.close(); } catch {} this.closed = true; } async pipe(body) { this.writer.releaseLock(); await body.pipeTo(this.writable, { preventClose: true }); this.writer = this.writable.getWriter(); } onAbort(listener) { this.abortSubscribers.push(listener); } abort() { if (!this.aborted) { this.aborted = true; this.abortSubscribers.forEach((subscriber) => subscriber()); } } }; //#endregion //#region ../../node_modules/hono/dist/helper/streaming/sse.js var SSEStreamingApi = class extends StreamingApi { constructor(writable, readable) { super(writable, readable); } async writeSSE(message) { const dataLines = (await resolveCallback(message.data, HtmlEscapedCallbackPhase.Stringify, false, {})).split("\n").map((line) => { return `data: ${line}`; }).join("\n"); const sseData = [ message.event && `event: ${message.event}`, dataLines, message.id && `id: ${message.id}`, message.retry && `retry: ${message.retry}` ].filter(Boolean).join("\n") + "\n\n"; await this.write(sseData); } }; //#endregion //#region private/server/utils/index.ts /** * Generates a short numeric hash from a string input. * * @param input - The input to use for generating the hash. * * @returns A numeric hash. */ const generateHashSync = (input) => { let hash = 0; for (let i = 0; i < input.length; i++) hash = Math.imul(31, hash) + input.charCodeAt(i) | 0; return hash >>> 0; }; var ResponseStream = class extends SSEStreamingApi { /** The first request object provided by the client. */ request; /** The first response object returned to the client. */ response; /** * The time at which the last update started processing. If the value is `null`, no * update started processing yet. */ lastUpdate = null; /** * The results of the read queries that were executed last. Allows for caching read * query results between flushes, to not run all read queries every time. */ lastResults = []; /** Allows for tracking whether the response is ready to be returned. */ headersReady; setHeadersReady; headersMarkedReady = false; constructor(request) { const { readable, writable } = new TransformStream(); super(writable, readable); this.request = request; this.response = new Response(this.responseReadable, { headers: { "Transfer-Encoding": "chunked", "Content-Type": "text/plain", "Cache-Control": "no-cache, no-transform", "X-Accel-Buffering": "no" } }); this.headersReady = new Promise((resolve) => { this.setHeadersReady = () => { if (this.headersMarkedReady) return; this.headersMarkedReady = true; resolve(); }; }); } /** * Consumes a `Response`, which is converted into a chunk on the current stream. * * @param type - The type of chunk that should be sent. * @param response - The response that should be consumed. * * @returns A `Promise` that will resolve once the chunk has been flushed. */ writeChunk(type, response) { response.headers.forEach((value, key) => { if (key === "set-cookie") this.response.headers.append(key, value); else this.response.headers.set(key, value); }); this.setHeadersReady(); const newURL = response.headers.get("Content-Location"); if (newURL) this.request = new Request(new URL(newURL, this.request.url), this.request); return this.writeSSE({ id: `${crypto.randomUUID()}-${import.meta.env.__BLADE_BUNDLE_ID}`, event: type, data: response.text() }); } }; //#endregion export { generateHashSync as n, ResponseStream as t };