All files / packages/topic/src codec.ts

81.81% Statements 18/22
70% Branches 7/10
70% Functions 7/10
81.81% Lines 18/22

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73                      14x   14x             85x   28x   1098067x 16636x     28x   2x 2x     28x     28x   1x 1x     1x               14x           14x 14x     14x                      
import * as zlib from 'node:zlib'
import { Codec } from '@ydbjs/api/topic'
 
export interface CompressionCodec {
	codec: Codec | number
	compress(payload: Uint8Array): Uint8Array
	decompress(payload: Uint8Array): Uint8Array
}
 
// node:zlib gained zstd in Node.js 22.15 / 23.8; the package supports Node >= 20.19,
// so the built-in ZSTD codec is available only when the runtime provides it.
let hasZstd = typeof zlib.zstdCompressSync === 'function'
 
let zstdUnsupported = function zstdUnsupported(): Error {
	return new Error(
		'Built-in ZSTD codec requires node:zlib zstd support (Node.js 22.15+ / 23.8+) — on runtimes without it provide a custom CompressionCodec for Codec.ZSTD'
	)
}
 
export function getCodec(codec: Codec): CompressionCodec {
	switch (codec) {
		case Codec.RAW:
			return {
				codec: Codec.RAW,
				compress: (payload) => payload,
				decompress: (payload) => payload,
			}
		case Codec.GZIP:
			return {
				codec: Codec.GZIP,
				compress: (payload) => zlib.gzipSync(payload),
				decompress: (payload) => zlib.gunzipSync(payload),
			}
		case Codec.ZSTD:
			Iif (!hasZstd) {
				throw zstdUnsupported()
			}
			return {
				codec: Codec.ZSTD,
				compress: (payload) => zlib.zstdCompressSync(payload),
				decompress: (payload) => zlib.zstdDecompressSync(payload),
			}
		default:
			throw new Error(`Unsupported codec: ${codec}`)
	}
}
 
export type CodecMap = Map<Codec | number, CompressionCodec>
 
// ZSTD is present only when the runtime supports it — a reader on older Node that
// receives ZSTD data gets the actionable "register it in codecMap" decode error.
export const defaultCodecMap: CodecMap = new Map([
	[Codec.RAW, getCodec(Codec.RAW)],
	[Codec.GZIP, getCodec(Codec.GZIP)],
	...(hasZstd ? [[Codec.ZSTD, getCodec(Codec.ZSTD)] as const] : []),
])
 
export const RAW_CODEC: CompressionCodec = getCodec(Codec.RAW)
export const GZIP_CODEC: CompressionCodec = getCodec(Codec.GZIP)
// Import-safe on every supported Node version; throws with the Node-version hint
// at first use instead of a bare TypeError from the missing zlib function.
export const ZSTD_CODEC: CompressionCodec = hasZstd
	? getCodec(Codec.ZSTD)
	: {
			codec: Codec.ZSTD,
			compress: () => {
				throw zstdUnsupported()
			},
			decompress: () => {
				throw zstdUnsupported()
			},
		}