type ObjectValues = T[keyof T]; /** * Supported message compression codecs. * * Use the enum values instead of raw strings so that adding a new codec in * the future is a single-place change and consumers benefit from IDE * auto-complete. * * @example * new MyPublisher(deps, { codec: MessageCodecEnum.ZSTD }) */ export declare const MessageCodecEnum: { /** zstd compression via Node.js built-in `zlib` (requires Node.js >=22.15.0). */ readonly ZSTD: "zstd"; }; export type MessageCodec = ObjectValues; declare const CODEC_FIELD = "__mqtCodec"; declare const DATA_FIELD = "__mqtData"; export type CodecEnvelope = { [CODEC_FIELD]: string; [DATA_FIELD]: string; }; /** * Low-level interface for a compression codec. * * Implement this interface to plug in a custom compression algorithm. * The built-in implementation (`ZstdCodecHandler`, exported from * `@message-queue-toolkit/core`) uses Node.js built-in `zlib` zstd support. * * All three methods are required: * - `compress` / `decompress` are used for the inline (non-offloaded) path on both sides. * - `createCompressStream` is used by the streaming offload path to pipe serialized * JSON directly through compression into the payload store without buffering the * full payload in memory. * * Note the deliberate asymmetry: there is no `createDecompressStream`. Decompression is * always buffer-based (`decompress`) because the consumer must `JSON.parse` the whole * payload anyway — a streaming decompressor could not avoid materializing it. For an * offloaded compressed payload this means the compressed bytes and the decompressed * payload are both briefly resident in memory; bound the worst case with the * `maxDecompressedBytes` argument of {@link ZstdCodecHandler} (or the equivalent in a * custom handler). */ export interface MessageCodecHandler { compress(data: Buffer): Promise; /** * Decompresses a full compressed buffer. Buffer-based by design (see the interface * note above); a custom implementation should cap the decompressed size to guard * against decompression bombs. */ decompress(data: Buffer): Promise; /** Returns a Transform stream that compresses its input using this codec. */ createCompressStream(): import('node:stream').Transform; } /** * Passed to the `codec` option to select a compression codec. * * - **String form** (`MessageCodec`): selects one of the built-in codecs * (e.g. `MessageCodecEnum.ZSTD`). * - **Object form** (`{ name, handler }`): plugs in a custom * `MessageCodecHandler` implementation under a user-chosen name. The name * is written into the `__mqtCodec` field of every envelope so the consumer * can identify and route to the correct handler. * * @example Built-in zstd * new MyPublisher(deps, { codec: MessageCodecEnum.ZSTD }) * * @example Custom codec * import { LZ4Handler } from './lz4Handler.ts' * const codec = { name: 'lz4', handler: new LZ4Handler() } * new MyPublisher(deps, { codec }) * new MyConsumer(deps, { codecs: [codec] }) // register the same codec on the consumer */ export type MessageCodecRegistration = MessageCodec | { name: string; handler: MessageCodecHandler; }; /** * Base64 pattern: groups of 4 chars from the alphabet, with at most 2 trailing `=` pads. * An empty string (compressed payload of 0 bytes) is also valid. * Exported so codec implementations can reuse it without duplicating the regex. */ export declare const BASE64_RE: RegExp; /** Built once at module load — avoids a fresh array allocation on every hot-path call. */ export declare const KNOWN_CODECS: ReadonlySet; /** * Structural check: returns true when `value` has the shape of a codec envelope — * a non-empty string `__mqtCodec` and a base64 `__mqtData` — **regardless of whether * the named codec is one this consumer can decode**. * * Detection is **presence-based**: extra sibling fields are allowed, because publishers * copy identity/routing fields (`id`, `type`, …) alongside the codec fields so * broker-side filtering (e.g. SNS body-scoped FilterPolicy) keeps working on compressed * messages. This mirrors how an offloaded-payload pointer is recognised by its * `payloadRef` shape, not by an exact object shape. * * Consumers use this (rather than {@link isCodecEnvelope}) so an envelope for an * unregistered codec can be told apart from an ordinary message and surfaced as a * misconfiguration instead of being validated as an incomplete skeleton. The cheap * `in` checks run first, so a non-envelope value returns without allocating anything. */ export declare function hasCodecEnvelopeShape(value: unknown): value is CodecEnvelope; /** * Returns true when `value` is a codec envelope **for a codec in `knownCodecs`** — i.e. * one this consumer can actually decode. Combines the structural * {@link hasCodecEnvelopeShape} check with a codec-name lookup. * * Pass `knownCodecs` to restrict the match to the codecs your consumer is configured to * handle. Defaults to the built-in codec set — backwards-compatible for consumers that * don't configure a codec. */ export declare function isCodecEnvelope(value: unknown, knownCodecs?: ReadonlySet): value is CodecEnvelope; export {};