denoland / std

The Deno Standard Library
https://jsr.io/@std
MIT License
3.01k stars 604 forks source link

proposal: Introduce the Brotli Compression Algorithm #4707

Open BlackAsLight opened 4 months ago

BlackAsLight commented 4 months ago

Bouncing off of what was briefly discussed on discord, I'm opening this issue to discuss the possibility of having the Brotli compression algorithm (RFC7932) added somewhere to Deno's STD. I would like to have a go at implementing the algorithm myself, but would also like feedback on the idea from everyone else.

I think Brotli would be a good addition to the STD as it's a widely supported compression format supported by almost all browsers under the Accept-Encoding header and would allow people to easily compress their content without additional tooling. Brotli is also supposedly faster than Gzip, although I doubt a pure JavaScript implementation of Brotli would beat the built in implementation of Gzip, but would still be beneficial for when serving static content as that can all be pre-brotli-ed.

The default suggested location for such an addition to be introduced was under @std/streams, although this doesn't seem like a good fit in practicality as the contents of @std/streams is more focused towards utility streams. On a side note, there also seems to be quite an inconsistency about whether a file format get's its own module named after itself (csv, toml, yaml) or if it gets placed under its type of category (archive/tar).

iuioiua commented 4 months ago

To reiterate, I suggested std/streams just so there are no blockers to getting the ball rolling with an implementation. I think such an implementation should exist in std/compress (or similar). However, more discussion is needed before committing to a whole new package.

iuioiua commented 4 months ago

Either way, I like the idea of a BrotliCompressionStream() and BrotliDecompressionStream().

iuioiua commented 2 months ago

How about implementing extended versions of CompressionStream and DecompressionStream that also support br as the argument? If constructed with anything other than br, it delegates to using the runtime.

Whichever way we go, we'd gladly take a look at a PR that does this in @std/compress.

BlackAsLight commented 2 months ago

How about implementing extended versions of CompressionStream and DecompressionStream that also support br as the argument? If constructed with anything other than br, it delegates to using the runtime.

Whichever way we go, we'd gladly take a look at a PR that does this in @std/compress.

You mean something like this?

self.CompressionStream = function () {
    const compressionStream = CompressionStream
    return class {
        #readable: ReadableStream<Uint8Array>
        #writable: WritableStream<Uint8Array>
        constructor(format: string) {
            const { readable, writable } = format === 'br' ? new BrotliCompressionStream() : new compressionStream(format)
            this.#readable = readable
            this.#writable = writable
        }

        get readable(): ReadableStream<Uint8Array> {
            return this.#readable
        }

        get writable(): WritableStream<Uint8Array> {
            return this.#writable
        }
    }
}()
iuioiua commented 2 months ago

We don't want to overwrite globals. It should be an exported class, if anything.