slate

slate:brotli

This module is behind the brotli build feature, which is on by default and is in every released binary. It is a feature because libbrotli has to be installed before slate will build at all — see Building without a library. A build without it also stops offering Content-Encoding: br, slate:http reaching for the same two names from inside the built-in scope.

import { compress, decompress } from slate:brotli

val page = toBytes(repeat("<p>hello</p>", 40))
val small = compress(page, 5)               // quality 0-11
val back = decompress(small, 1 << 20)       // the limit is not optional

print(small.length < page.length, small is bytes)
print(back.ok, back.value == page)
print(decompress(toBytes("not brotli"), 1 << 20).ok)
true true
true true
false

Both answer bytes, and data may be text, a buffer or an array of numbers — so a program written against the array shape reads exactly as it did.

The two channels

compress faults — it cannot fail on input the program already holds. decompress answers a result, because what is being decompressed came from somewhere else: a request body that is not a brotli stream is an ordinary thing to be sent and a 400 to answer, not a defect in the program reading it.

The three failures are three sentences, since they mean three different things to whoever sent the bytes: expands past the N bytes it was allowed, ends in the middle, is not a brotli stream.

The limit is required

A brotli stream carries no length and a crafted one of a few hundred bytes expands without bound. There is no form of decompress that omits the limit.

Not in a browser

No JavaScript host has a brotli encoder, so compress and decompress refuse under slate js, naming brotli rather than promising a release. slate:gzip is the compression a browser has, and it is promise-shaped for that reason; this module is synchronous and stays so.

slate:http compresses a response without asking the handler; that page says what the rules are.

Search

Esc
↑↓ to navigate ↵ to open Esc to close