2026-07-29 15:51:39 +07:00
|
|
|
/** Compression algorithm for chunked file storage. */
|
|
|
|
|
export type CompressionAlgorithm = 'gzip' | null;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Optionally compress a chunk with gzip.
|
|
|
|
|
*
|
|
|
|
|
* Compression is skipped if:
|
|
|
|
|
* - The `compress` flag is false.
|
|
|
|
|
* - The chunk is smaller than `compressionMinSizeBytes`.
|
|
|
|
|
* - The compressed result is larger than the original.
|
|
|
|
|
*
|
|
|
|
|
* @param chunk - The raw chunk buffer.
|
|
|
|
|
* @param compress - Whether compression is enabled.
|
|
|
|
|
* @param compressionMinSizeBytes - Minimum chunk size to attempt compression.
|
|
|
|
|
* @returns The (possibly compressed) bytes and the algorithm used.
|
|
|
|
|
*/
|
|
|
|
|
export const maybeCompressChunk = (
|
|
|
|
|
chunk: Buffer,
|
|
|
|
|
compress: boolean,
|
|
|
|
|
compressionMinSizeBytes: number,
|
|
|
|
|
): { bytes: Buffer; compressionAlgorithm: CompressionAlgorithm } => {
|
|
|
|
|
if (!compress || chunk.byteLength < compressionMinSizeBytes) {
|
|
|
|
|
return { bytes: chunk, compressionAlgorithm: null };
|
|
|
|
|
}
|
|
|
|
|
|
2026-09-06 00:11:00 +07:00
|
|
|
const gzipped = Bun.gzipSync(chunk as Uint8Array<ArrayBuffer>);
|
2026-07-29 15:51:39 +07:00
|
|
|
if (gzipped.byteLength >= chunk.byteLength) {
|
|
|
|
|
return { bytes: chunk, compressionAlgorithm: null };
|
|
|
|
|
}
|
|
|
|
|
|
2026-09-06 00:11:00 +07:00
|
|
|
// CRITICAL: Bun.gzipSync returns a plain Uint8Array, NOT a Buffer.
|
|
|
|
|
// Telegraf (telegram.sendDocument) only recognises Buffer/Blob/stream
|
|
|
|
|
// sources as file uploads — a plain Uint8Array yields an empty multipart
|
|
|
|
|
// body and Telegram rejects with "400: there is no document in the request".
|
|
|
|
|
// Wrap in Buffer.from(...) so chunked uploads of compressible files (MP4,
|
|
|
|
|
// zip, text, etc.) actually work.
|
|
|
|
|
return { bytes: Buffer.from(gzipped), compressionAlgorithm: 'gzip' };
|
2026-07-29 15:51:39 +07:00
|
|
|
};
|