Compression primitives

Elide ships a shared compression layer in dev.elide.lang.javascript.compression. It is host-internal — guest JavaScript does not see it directly. The Node zlib module and the WHATWG CompressionStream / DecompressionStream globals consume it.

Public types

TypePurpose
CompressionPrimitivesStatic facade for one-shot compress / decompress plus stream factories.
CompressionStreamIncremental encoder. AutoCloseable.
DecompressionStreamIncremental decoder. AutoCloseable.
CompressionFormatDEFLATE_RAW, DEFLATE, GZIP, BROTLI, ZSTD.
FlushModeNO_FLUSH, SYNC_FLUSH, FULL_FLUSH, FINISH.
CompressionOptionsEncoder configuration: level, strategy, optional preset dictionary.
CompressionExceptionMalformed input — wrong magic, truncation, CRC / length mismatch.
CompressionBackendSPI for engine implementations (JDK, FFM-Rust).
CompressionBackendsRegistry holding the active backend; install hook for the runtime.

Backends

Two backends share CompressionBackend. The active one is held by CompressionBackends.current() and swapped via install. The default is the JDK fallback; runtime startup activates the native backend after libelideruntime has loaded.
BackendFormatsNotes
JdkCompressionFallbackDEFLATE_RAW, DEFLATE, GZIPjava.util.zip.{Deflater,Inflater}. Rejects Brotli / Zstd; rejects flush modes the JDK does not surface (PARTIAL_FLUSH, Z_BLOCK, Z_TREES). Honours non-default compression strategies.
NativeCompressionAll five formatsFFM downcalls into a Rust shim around flate2 + brotli + zstd. Activated by NativeCompression.tryInstall() once the runtime library is on java.library.path. Honours all flush modes that the underlying codecs expose. Refuses non-default compression strategies — the Rust port of zlib does not surface them; install the JDK fallback for those calls.

Streaming protocol

java
try (var stream = CompressionPrimitives.newCompressor(CompressionFormat.GZIP)) {
  while (more) {
    byte[] out = stream.update(chunk, 0, chunk.length, FlushMode.NO_FLUSH);
    sink.write(out);
  }
  sink.write(stream.finish());
}
  • update returns whatever the encoder chose to emit under the requested flush mode — possibly an empty array.
  • finish drains the encoder, writes the format trailer (zlib Adler-32, gzip CRC-32 + length), and marks the stream done. Subsequent update / finish calls on the same stream throw IllegalStateException.
  • close releases the underlying engine. A Cleaner-registered safety net on the backend reclaims the engine if the caller drops the stream without closing.

One-shot helpers

java
byte[] gzipped = CompressionPrimitives.compress(CompressionFormat.GZIP, input);
byte[] back = CompressionPrimitives.decompress(CompressionFormat.GZIP, gzipped);

These build a stream, push the entire input, finalise, and drop the stream. For inputs of bounded size this is the simpler call; for producer-paced data, use the streaming form.

Provider model

CompressionBackends mirrors the HostEnvironment provider pattern: a single swap-able global, a default safe-fallback, and an install(...) hook that should fire during runtime initialisation before any guest realm boots. This keeps the public CompressionStream / DecompressionStream calls agnostic to which engine is in effect.