Skip to content
LogoLogo

@portable/compress

Functions

Compress.decode

Decompresses bytes with DecompressionStream. A gzip file with several members decodes to all of them joined, as gunzip does.

async function decode(
  data: Uint8Array,
  options: decode.Options = {},
): Promise<Uint8Array<ArrayBuffer>>;
OptionTypeDefaultDescription
formatFormat'gzip'
maxBytesnumberInfinityFail with MaxBytesError once the output grows past this many bytes.
signalAbortSignalRejects with signal.reason when aborted, and stops the compression stream.
import * as Compress from '@portable/compress';
 
const response = await fetch('https://example.com/data.json.gz');
const bytes = await Compress.decode(await response.bytes(), {
  maxBytes: 100_000_000,
});

Compress.encode

Compresses bytes or UTF-8 text with CompressionStream.

async function encode(
  data: Uint8Array | string,
  options: encode.Options = {},
): Promise<Uint8Array<ArrayBuffer>>;
OptionTypeDefaultDescription
formatFormat'gzip'
signalAbortSignalRejects with signal.reason when aborted, and stops the compression stream.
import * as Compress from '@portable/compress';
 
const gzipped = await Compress.encode('hello world');
const zlib = await Compress.encode(bytes, { format: 'deflate' });

Compress.crc32

Computes the CRC-32 checksum used by gzip, zip and PNG. Strings are encoded as UTF-8. Pass the previous result as previous to continue a checksum over data that arrives in pieces.

function crc32(data: Uint8Array | string, previous: number = ): number;
import * as Compress from '@portable/compress';
 
Compress.crc32('hello'); // 0x3610a686
Compress.crc32(' world', Compress.crc32('hello')) ===
  Compress.crc32('hello world'); // true

Classes

Compress.DecoderStream

A TransformStream that decompresses with DecompressionStream, adding a maxBytes limit and the package's error classes. Input chunks that arrive while the decompressor is busy are joined into one write, so small network chunks don't each pay the decompressor's per-chunk cost.

class DecoderStream extends TransformStream<
  Uint8Array,
  Uint8Array<ArrayBuffer>
> {
  constructor(options: DecoderStream.Options = {});
  readonly readable: ReadableStream<Uint8Array<ArrayBuffer>>;
  readonly writable: WritableStream<Uint8Array>;
}
OptionTypeDefaultDescription
formatFormat'gzip'
maxBytesnumberInfinityFail with MaxBytesError and cancel the input once the output grows past this many bytes.
signalAbortSignalErrors the stream with signal.reason when the signal aborts, which makes pipeThrough cancel the source.
import * as Compress from '@portable/compress';
 
const response = await fetch('https://example.com/export.ndjson.gz');
const body = response.body!.pipeThrough(
  new Compress.DecoderStream({ maxBytes: 1_000_000_000 }),
);

Errors

Compress.InvalidInputError

Thrown when compressed input is malformed, fails its checksum, or has data after its end.

class InvalidInputError extends Errors.InvalidInputError {
  constructor(
    message: string = 'Compressed input is invalid.',
    options?: ErrorOptions,
  );
  readonly kind: string;
}
import * as Compress from '@portable/compress';
 
try {
  await Compress.decode(new TextEncoder().encode('not gzip'));
} catch (error) {
  if (error instanceof Compress.InvalidInputError) {
    console.log(error.message);
  }
}

Compress.MaxBytesError

Thrown when decompressed output grows past maxBytes.

class MaxBytesError extends Errors.MaxBytesError {
  constructor(options: Errors.MaxBytesError.Options);
  readonly kind: string;
}
import * as Compress from '@portable/compress';
 
try {
  await Compress.decode(upload, { maxBytes: 10_000_000 });
} catch (error) {
  if (error instanceof Compress.MaxBytesError) {
    console.log(`larger than ${error.maxBytes} bytes`);
  }
}

Compress.TruncatedError

Thrown when compressed input ends before the end of the compressed stream.

class TruncatedError extends Errors.TruncatedError {
  constructor(
    message: string = 'Compressed input ended early.',
    options?: ErrorOptions,
  );
  readonly kind: string;
}
import * as Compress from '@portable/compress';
 
const gzipped = await Compress.encode('hello world');
try {
  await Compress.decode(gzipped.subarray(0, 10));
} catch (error) {
  if (error instanceof Compress.TruncatedError) {
    console.log('download was cut off');
  }
}

Types

Compress.Format

A format that CompressionStream and DecompressionStream support: gzip (RFC 1952), zlib (RFC 1950) or raw deflate (RFC 1951).

type Format =  |  | ;