| Server IP : 159.203.156.69 / Your IP : 216.73.217.172 Web Server : nginx/1.24.0 System : Linux main-ubuntu 6.8.0-71-generic #71-Ubuntu SMP PREEMPT_DYNAMIC Tue Jul 22 16:52:38 UTC 2025 x86_64 User : root ( 0) PHP Version : 8.3.6 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/tanviranik.com/node_modules/vinext/dist/utils/ |
Upload File : |
{"version":3,"file":"text-stream.js","names":[],"sources":["../../src/utils/text-stream.ts"],"sourcesContent":["/**\n * Helpers for the repeated `new TextDecoder()` + `ReadableStream` chunk-loop\n * pattern used across the server. Each helper handles the streaming-decode\n * boundary correctly (final empty `decoder.decode()` flush so any incomplete\n * trailing UTF-8 sequence is reported).\n *\n * Sites with additional load-bearing behaviour (line-buffered transforms,\n * raw-byte accumulators, mixed string/Uint8Array streams, cache-key body\n * canonicalisation) intentionally still inline their own decoder.\n */\n\n/**\n * Drain a UTF-8 byte stream and return the full decoded text. The stream\n * reader is released on both success and failure.\n */\nexport async function readStreamAsText(stream: ReadableStream<Uint8Array>): Promise<string> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n const chunks: string[] = [];\n\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n chunks.push(decoder.decode(value, { stream: true }));\n }\n chunks.push(decoder.decode());\n return chunks.join(\"\");\n } finally {\n reader.releaseLock();\n }\n}\n\n/**\n * Drain a UTF-8 byte stream up to `maxBytes` of *raw* input, returning the\n * decoded text. If the raw size limit is exceeded, the reader is cancelled\n * and `onLimitExceeded` is invoked; it MUST throw — its return type is\n * `never` to enforce that. Each caller passes its own error type.\n *\n * The size check is on raw bytes (pre-decode) to bound memory before\n * paying the decoder cost.\n */\nexport async function readStreamAsTextWithLimit(\n stream: ReadableStream<Uint8Array>,\n maxBytes: number,\n onLimitExceeded: () => never,\n): Promise<string> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n const chunks: string[] = [];\n let totalSize = 0;\n\n try {\n for (;;) {\n const result = await reader.read();\n if (result.done) {\n break;\n }\n\n totalSize += result.value.byteLength;\n if (totalSize > maxBytes) {\n await reader.cancel();\n onLimitExceeded();\n }\n\n chunks.push(decoder.decode(result.value, { stream: true }));\n }\n\n chunks.push(decoder.decode());\n return chunks.join(\"\");\n } finally {\n reader.releaseLock();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAeA,eAAsB,iBAAiB,QAAqD;CAC1F,MAAM,SAAS,OAAO,WAAW;CACjC,MAAM,UAAU,IAAI,aAAa;CACjC,MAAM,SAAmB,EAAE;CAE3B,IAAI;EACF,SAAS;GACP,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,MAAM;GAC3C,IAAI,MACF;GAEF,OAAO,KAAK,QAAQ,OAAO,OAAO,EAAE,QAAQ,MAAM,CAAC,CAAC;;EAEtD,OAAO,KAAK,QAAQ,QAAQ,CAAC;EAC7B,OAAO,OAAO,KAAK,GAAG;WACd;EACR,OAAO,aAAa;;;;;;;;;;;;AAaxB,eAAsB,0BACpB,QACA,UACA,iBACiB;CACjB,MAAM,SAAS,OAAO,WAAW;CACjC,MAAM,UAAU,IAAI,aAAa;CACjC,MAAM,SAAmB,EAAE;CAC3B,IAAI,YAAY;CAEhB,IAAI;EACF,SAAS;GACP,MAAM,SAAS,MAAM,OAAO,MAAM;GAClC,IAAI,OAAO,MACT;GAGF,aAAa,OAAO,MAAM;GAC1B,IAAI,YAAY,UAAU;IACxB,MAAM,OAAO,QAAQ;IACrB,iBAAiB;;GAGnB,OAAO,KAAK,QAAQ,OAAO,OAAO,OAAO,EAAE,QAAQ,MAAM,CAAC,CAAC;;EAG7D,OAAO,KAAK,QAAQ,QAAQ,CAAC;EAC7B,OAAO,OAAO,KAAK,GAAG;WACd;EACR,OAAO,aAAa"}