-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: CompressionStream #11728
feat: CompressionStream #11728
Conversation
I just looked into this. I think the only way we can get it to work is by splitting reading from a compressor and writing into it into seperate ops that happen in parallel. This is because a single write may not always correspond to a single read. How exactly this can be most trivially implemented is still up for debate. I'll revisit this again. |
This could be a nice solution for compression in Deno: it's standard compliant and should be more performant than third-party js/wasm modules. As I understand, exposing the zlib in Deno the way Node does is problematic, but this would cover most use cases for compression without exposing zlib. |
Please include brotli support. |
We wont. it isnt part of the specification |
Maybe we can develop |
I assume the most common use case for this API will be online compression of response bodies. In that case, the default compression (zlib's level 6) is good enough, and arguably it's a much better choice than say brotli in most cases due to the complexity/performance trade off. |
I used CompressionStream in web application development and found it very fast and convenient, so I would like Deno to implement it as well! |
# Conflicts: # Cargo.lock # ext/web/Cargo.toml
@crowlKats @lucacasonato This is close to working condition now. PTAL. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! The JS side bindings are not yet quite correct. I'll clean them up tomorrow, but then this is good to land!
Great job on figuring out this flate2 stuff. It looks so simple now that it's done 🙂
ext/web/compression.rs
Outdated
} | ||
Inner::GzEncoder(d) => { | ||
d.write_all(&input)?; | ||
d.get_mut().drain(..).collect() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the trick I couldn't figure out in previous attempts. Great! 👍
@ry You either don't have an up to date WPT submodule, or you didn't run |
Boiled it down to this test case failing: const deflateChunkValue = new Uint8Array([120, 156, 75, 173, 40, 72, 77, 46, 73, 77, 81, 200, 47, 45, 41, 40, 45, 1, 0, 48, 173, 6, 36]);
const trueChunkValue = new TextEncoder().encode('expected output');
const ds = new DecompressionStream('deflate');
const reader = ds.readable.getReader();
const writer = ds.writable.getWriter();
const writePromise = writer.write(deflateChunkValue);
const { done, value } = await reader.read();
assert_array_equals(Array.from(value), trueChunkValue, "value should match");
await writePromise;
await writer.close(); The test fails on the line
|
Pushed the changes required to fix the IDL stuff. The happy case is not working at all though. Always fails with |
@lucacasonato Yes I experienced that too. This seems to be a bug deep inside Deno somewhere, not in this compression stream - there are no async ops. For example if I run: import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
const deflateChunkValue = new Uint8Array([120, 156, 75, 173, 40, 72, 77, 46, 73, 77, 81, 200, 47, 45, 41, 40, 45, 1, 0, 48, 173, 6, 36]);
const trueChunkValue = new TextEncoder().encode('expected output');
async function main() {
const ds = new DecompressionStream('deflate');
const reader = ds.readable.getReader();
const writer = ds.writable.getWriter();
console.log("A", Deno.resources());
await writer.write(deflateChunkValue);
console.log("B", Deno.resources());
const { done, value } = await reader.read();
assertEquals(Array.from(value), trueChunkValue, "value should match");
console.log("C", Deno.resources());
}
main(); It never gets to the second |
Mh, that looks like a bug in the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this first pass is done. LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM too, nice work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Closes #7113