UNPKG

@catbee/utils

Version:

A modular, production-grade utility toolkit for Node.js and TypeScript, designed for robust, scalable applications (including Express-based services). All utilities are tree-shakable and can be imported independently.

145 lines (141 loc) 4.99 kB
/* * The MIT License * * Copyright (c) 2026 Catbee Technologies. https://catbee.in/license * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ import { Readable, Transform } from 'stream'; var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); function bufferToStream(data) { const readable = new Readable(); readable.push(data); readable.push(null); return readable; } __name(bufferToStream, "bufferToStream"); async function streamToBuffer(stream) { return new Promise((resolve, reject) => { const chunks = []; stream.on("data", (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk))); stream.on("end", () => resolve(Buffer.concat(chunks))); stream.on("error", reject); }); } __name(streamToBuffer, "streamToBuffer"); async function streamToString(stream, encoding = "utf8") { const buffer = await streamToBuffer(stream); return buffer.toString(encoding); } __name(streamToString, "streamToString"); function createThrottleStream(bytesPerSecond) { let bytesSent = 0; let startTime = Date.now(); return new Transform({ transform(chunk, _encoding, callback) { const elapsedSeconds = (Date.now() - startTime) / 1e3; const targetBytes = bytesPerSecond * elapsedSeconds; const chunkSize = chunk.length; if (bytesSent + chunkSize <= targetBytes) { bytesSent += chunkSize; callback(null, chunk); return; } const delay = ((bytesSent + chunkSize) / bytesPerSecond - elapsedSeconds) * 1e3; setTimeout(() => { bytesSent += chunkSize; callback(null, chunk); }, delay); } }); } __name(createThrottleStream, "createThrottleStream"); function createBatchStream(size, options = {}) { const objectMode = options.objectMode !== false; let batch = []; let buffers = []; let bufferSize = 0; return new Transform({ objectMode, transform(chunk, _encoding, callback) { if (objectMode) { batch.push(chunk); if (batch.length >= size) { this.push(batch); batch = []; } } else { const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk); buffers.push(buffer); bufferSize += buffer.length; let combined = Buffer.concat(buffers, bufferSize); while (combined.length >= size) { this.push(combined.slice(0, size)); combined = combined.slice(size); } buffers = combined.length > 0 ? [ combined ] : []; bufferSize = combined.length; } callback(); }, flush(callback) { if (objectMode && batch.length > 0) { this.push(batch); } else if (!objectMode && buffers.length > 0 && bufferSize > 0) { let combined = Buffer.concat(buffers, bufferSize); while (combined.length >= size) { this.push(combined.slice(0, size)); combined = combined.slice(size); } if (combined.length > 0) { this.push(combined); } } callback(); } }); } __name(createBatchStream, "createBatchStream"); function createLineStream(options = {}) { const { encoding = "utf8", includeNewlines = false } = options; let buffer = ""; return new Transform({ objectMode: true, transform(chunk, _encoding, callback) { const str = buffer + (Buffer.isBuffer(chunk) ? chunk.toString(encoding) : chunk); const lines = str.split(/\r?\n/); buffer = lines.pop() || ""; for (const line of lines) { this.push(includeNewlines ? line + "\n" : line); } callback(); }, flush(callback) { if (buffer) { this.push(buffer); } callback(); } }); } __name(createLineStream, "createLineStream"); export { bufferToStream, createBatchStream, createLineStream, createThrottleStream, streamToBuffer, streamToString };