zlib-streams 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Makefile +1 -0
- package/README.md +40 -0
- package/dist/zlib-streams.js +9 -4
- package/package.json +1 -1
- package/src/wasm/api/zlib-streams.js +9 -4
package/Makefile
CHANGED
|
@@ -300,6 +300,7 @@ run_all_tests: dist/zlib-streams-dev.wasm
|
|
|
300
300
|
@node src/wasm/tests/test_stream_abort_releases_memory.js dist/zlib-streams-dev.wasm
|
|
301
301
|
# Bytes after the end of the stream rejected, as the platform inflaters do
|
|
302
302
|
@node src/wasm/tests/test_trailing_data.js dist/zlib-streams-dev.wasm
|
|
303
|
+
@node src/wasm/tests/test_unknown_format.js dist/zlib-streams-dev.wasm
|
|
303
304
|
@echo "Completed run_all_tests"
|
|
304
305
|
|
|
305
306
|
dist/zlib-streams-dev.wasm: $(WASM_SRCS)
|
package/README.md
CHANGED
|
@@ -42,5 +42,45 @@ Output: `dist/zip-module.wasm`
|
|
|
42
42
|
|
|
43
43
|
The files in `dist/` are tracked, so a checkout leaves them with the same timestamp as the sources and `make dist/<file>` reports them up to date even when the sources changed. The three targets above always rebuild their file; the test targets depend on the file rules and rebuild only when a source is newer. Rebuild and commit `dist/` in the same commit as a change to `src/`.
|
|
44
44
|
|
|
45
|
+
## API
|
|
46
|
+
|
|
47
|
+
The npm package exports the JavaScript driver as `zlib-streams/zlib-streams.js` and the modules as `zlib-streams/zlib-streams.wasm` and `zlib-streams/zip-module.wasm`. The module imports nothing, so it is instantiated bare, and its exports are handed to the driver before any stream is created.
|
|
48
|
+
|
|
49
|
+
```js
|
|
50
|
+
import { setWasmExports, CompressionStreamZlib, DecompressionStreamZlib } from "zlib-streams/zlib-streams.js";
|
|
51
|
+
|
|
52
|
+
const wasmBytes = await (await fetch(import.meta.resolve("zlib-streams/zlib-streams.wasm"))).arrayBuffer();
|
|
53
|
+
const { instance } = await WebAssembly.instantiate(wasmBytes);
|
|
54
|
+
setWasmExports(instance.exports);
|
|
55
|
+
|
|
56
|
+
const compressed = new Blob(["Hello World"]).stream().pipeThrough(new CompressionStreamZlib("gzip", { level: 9 }));
|
|
57
|
+
const text = await new Response(compressed.pipeThrough(new DecompressionStreamZlib("gzip"))).text();
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Driver functions
|
|
61
|
+
|
|
62
|
+
- `setWasmExports(exports)`: registers the exports of an instantiated module (`malloc`, `free`, `memory` and the codec functions); throws `"Invalid WASM module"` when they are missing.
|
|
63
|
+
- `resetWasmExports()`: forgets the exports; the next stream throws `"WASM module not loaded"`.
|
|
64
|
+
- `setInitError(error)`: records why the module could not be loaded; the error is the `cause` of `"WASM module not loaded"`.
|
|
65
|
+
|
|
66
|
+
### Streams
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
new CompressionStreamZlib(format = "deflate", { level, outBuffer, inBufferSize })
|
|
70
|
+
new DecompressionStreamZlib(format = "deflate", { outBuffer, inBufferSize })
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Both classes return a `{ readable, writable }` pair usable with `pipeThrough()`. The formats are `"deflate"` (the zlib wrapper, RFC 1950), `"deflate-raw"` (RFC 1951, no wrapper), `"gzip"` and, for decompression only, `"deflate64-raw"`. `level` is the zlib compression level, 0 to 9, -1 (the default) for the zlib default. `outBuffer` and `inBufferSize` are the sizes in bytes of the output and input buffers allocated in the module heap, 64 KB each by default; input chunks are processed in slices of at most 32 KB.
|
|
74
|
+
|
|
75
|
+
The static properties `supportedFormats` (an array) and `requiresModule` (`true`) let a host check the formats and know that the classes are unusable until `setWasmExports()` has run.
|
|
76
|
+
|
|
77
|
+
### Errors
|
|
78
|
+
|
|
79
|
+
- Bytes following the end of a stream are rejected with `"trailing data after the end of the stream"`, whatever the format, as the `DecompressionStream` of the browsers does; concatenated gzip members are not decoded.
|
|
80
|
+
- A corrupted stream fails with `"process error:<code>"` carrying the zlib return code; a stream whose end is missing fails on close with `"end error:<code>"`.
|
|
81
|
+
- A failure to allocate memory, on construction or while processing, carries the property `code` set to `"Z_MEM_ERROR"`: `"allocation failed"` when the heap is exhausted, `"init failed:-4"` or `"process error:-4"` when zlib reports it.
|
|
82
|
+
|
|
83
|
+
The heap of the module is fixed, so the number of streams alive at the same time is bounded by their buffers; a stream releases its buffers when it closes, errors or is cancelled.
|
|
84
|
+
|
|
45
85
|
## License
|
|
46
86
|
See LICENSE for details.
|
package/dist/zlib-streams.js
CHANGED
|
@@ -34,6 +34,8 @@ const FORMAT_DEFLATE64_RAW = "deflate64-raw";
|
|
|
34
34
|
const FORMAT_GZIP = "gzip";
|
|
35
35
|
const Z_MEM_ERROR = -4;
|
|
36
36
|
const Z_MEM_ERROR_CODE = "Z_MEM_ERROR";
|
|
37
|
+
const COMPRESSION_FORMATS = [FORMAT_DEFLATE, FORMAT_DEFLATE_RAW, FORMAT_GZIP];
|
|
38
|
+
const DECOMPRESSION_FORMATS = [FORMAT_DEFLATE, FORMAT_DEFLATE_RAW, FORMAT_GZIP, FORMAT_DEFLATE64_RAW];
|
|
37
39
|
|
|
38
40
|
let wasm, malloc, free, memory, initError;
|
|
39
41
|
|
|
@@ -62,6 +64,9 @@ function setZlibCode(error, result) {
|
|
|
62
64
|
}
|
|
63
65
|
|
|
64
66
|
function _make(isCompress, type, options = {}) {
|
|
67
|
+
if (!(isCompress ? COMPRESSION_FORMATS : DECOMPRESSION_FORMATS).includes(type)) {
|
|
68
|
+
throw new TypeError("Unsupported format: " + type);
|
|
69
|
+
}
|
|
65
70
|
if (!wasm) {
|
|
66
71
|
const error = new Error("WASM module not loaded");
|
|
67
72
|
error.cause = initError;
|
|
@@ -299,7 +304,7 @@ export class DecompressionStreamZlib {
|
|
|
299
304
|
CompressionStreamZlib.requiresModule = true;
|
|
300
305
|
DecompressionStreamZlib.requiresModule = true;
|
|
301
306
|
// Constructing these classes before the module is loaded throws, so capability probes cannot rely
|
|
302
|
-
// on trying the constructor; the formats are declared instead,
|
|
303
|
-
//
|
|
304
|
-
CompressionStreamZlib.supportedFormats =
|
|
305
|
-
DecompressionStreamZlib.supportedFormats =
|
|
307
|
+
// on trying the constructor; the formats are declared instead, the lists _make() checks a format
|
|
308
|
+
// against before anything else.
|
|
309
|
+
CompressionStreamZlib.supportedFormats = COMPRESSION_FORMATS;
|
|
310
|
+
DecompressionStreamZlib.supportedFormats = DECOMPRESSION_FORMATS;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "WASM-based Compression Streams API implementation using zlib, with support for deflate64 decompression.",
|
|
4
4
|
"author": "Gildas Lormeau",
|
|
5
5
|
"license": "BSD-3-Clause",
|
|
6
|
-
"version": "1.
|
|
6
|
+
"version": "1.4.0",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"keywords": [
|
|
9
9
|
"deflate",
|
|
@@ -34,6 +34,8 @@ const FORMAT_DEFLATE64_RAW = "deflate64-raw";
|
|
|
34
34
|
const FORMAT_GZIP = "gzip";
|
|
35
35
|
const Z_MEM_ERROR = -4;
|
|
36
36
|
const Z_MEM_ERROR_CODE = "Z_MEM_ERROR";
|
|
37
|
+
const COMPRESSION_FORMATS = [FORMAT_DEFLATE, FORMAT_DEFLATE_RAW, FORMAT_GZIP];
|
|
38
|
+
const DECOMPRESSION_FORMATS = [FORMAT_DEFLATE, FORMAT_DEFLATE_RAW, FORMAT_GZIP, FORMAT_DEFLATE64_RAW];
|
|
37
39
|
|
|
38
40
|
let wasm, malloc, free, memory, initError;
|
|
39
41
|
|
|
@@ -62,6 +64,9 @@ function setZlibCode(error, result) {
|
|
|
62
64
|
}
|
|
63
65
|
|
|
64
66
|
function _make(isCompress, type, options = {}) {
|
|
67
|
+
if (!(isCompress ? COMPRESSION_FORMATS : DECOMPRESSION_FORMATS).includes(type)) {
|
|
68
|
+
throw new TypeError("Unsupported format: " + type);
|
|
69
|
+
}
|
|
65
70
|
if (!wasm) {
|
|
66
71
|
const error = new Error("WASM module not loaded");
|
|
67
72
|
error.cause = initError;
|
|
@@ -299,7 +304,7 @@ export class DecompressionStreamZlib {
|
|
|
299
304
|
CompressionStreamZlib.requiresModule = true;
|
|
300
305
|
DecompressionStreamZlib.requiresModule = true;
|
|
301
306
|
// Constructing these classes before the module is loaded throws, so capability probes cannot rely
|
|
302
|
-
// on trying the constructor; the formats are declared instead,
|
|
303
|
-
//
|
|
304
|
-
CompressionStreamZlib.supportedFormats =
|
|
305
|
-
DecompressionStreamZlib.supportedFormats =
|
|
307
|
+
// on trying the constructor; the formats are declared instead, the lists _make() checks a format
|
|
308
|
+
// against before anything else.
|
|
309
|
+
CompressionStreamZlib.supportedFormats = COMPRESSION_FORMATS;
|
|
310
|
+
DecompressionStreamZlib.supportedFormats = DECOMPRESSION_FORMATS;
|