@zip.js/zip.js 2.6.13 → 2.6.16

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/README.md CHANGED
@@ -1,13 +1,74 @@
1
- zip.js is an open-source library (BSD-3-Clause license) to zip and unzip files
2
- supporting multi-core compression, compression streams, Zip64 and encryption.
1
+ # Introduction
2
+
3
+ zip.js is an open-source library (BSD-3-Clause license) implemented in
4
+ JavaScript to compress and decompress zip files. It has been designed to handle
5
+ large amounts of data and notably supports multi-core compression, compression
6
+ streams, Zip64 and encryption.
7
+
8
+ # Documentation
3
9
 
4
10
  See here for more info: https://gildas-lormeau.github.io/zip.js/
5
11
 
12
+ # Examples
13
+
14
+ ## Hello world
15
+
6
16
  ```js
17
+ import {
18
+ BlobReader,
19
+ BlobWriter,
20
+ TextReader,
21
+ TextWriter,
22
+ ZipReader,
23
+ ZipWriter,
24
+ } from "https://deno.land/x/zipjs/index.js";
25
+
7
26
  // ----
8
- // Hello world with zip.js (and Streams)
27
+ // Write the zip file
9
28
  // ----
10
29
 
30
+ // Creates a BlobWriter object where the zip content will be written.
31
+ const zipFileWriter = new BlobWriter();
32
+ // Creates a TextReader object storing the text of the entry to add in the zip
33
+ // (i.e. "Hello world!").
34
+ const helloWorldReader = new TextReader("Hello world!");
35
+
36
+ // Creates a ZipWriter object writing data via `zipFileWriter`, adds the entry
37
+ // "hello.txt" containing the text "Hello world!" via `helloWorldReader`, and
38
+ // closes the writer.
39
+ const zipWriter = new ZipWriter(zipFileWriter);
40
+ await zipWriter.add("hello.txt", helloWorldReader);
41
+ await zipWriter.close();
42
+
43
+ // Retrieves the Blob object containing the zip content into `zipFileBlob`. It
44
+ // is also returned by zipWriter.close() for more convenience.
45
+ const zipFileBlob = await zipFileWriter.getData();
46
+
47
+ // ----
48
+ // Read the zip file
49
+ // ----
50
+
51
+ // Creates a BlobReader object used to read `zipFileBlob`.
52
+ const zipFileReader = new BlobReader(zipFileBlob);
53
+ // Creates a TextWriter object where the content of the first entry in the zip
54
+ // will be written.
55
+ const helloWorldWriter = new TextWriter();
56
+
57
+ // Creates a ZipReader object reading the zip content via `zipFileReader`,
58
+ // retrieves metadata (name, dates, etc.) of the first entry, retrieves its
59
+ // content via `helloWorldWriter`, and closes the reader.
60
+ const zipReader = new ZipReader(zipFileReader);
61
+ const firstEntry = (await zipReader.getEntries()).shift();
62
+ const helloWorldText = await firstEntry.getData(helloWorldWriter);
63
+ await zipReader.close();
64
+
65
+ // Displays "Hello world!".
66
+ console.log(helloWorldText);
67
+ ```
68
+
69
+ ## Hello world with Streams
70
+
71
+ ```js
11
72
  import {
12
73
  BlobReader,
13
74
  ZipReader,
@@ -18,8 +79,8 @@ import {
18
79
  // Write the zip file
19
80
  // ----
20
81
 
21
- // Creates a TransformStream object where the zip content will be written in
22
- // the `writable` property.
82
+ // Creates a TransformStream object, the zip content will be written in the
83
+ // `writable` property.
23
84
  const zipFileWriter = new TransformStream();
24
85
  // Creates a Promise object resolved to the zip content returned as a Blob
25
86
  // object via the `readable` property of `zipFileWriter`.
@@ -30,8 +91,8 @@ const zipFileBlobPromise = new Response(zipFileWriter.readable).blob();
30
91
  const helloWorldReader = { readable: new Blob(["Hello world!"]).stream() };
31
92
 
32
93
  // Creates a ZipWriter object writing data via `zipFileWriter`, adds the entry
33
- // "hello.txt" containing the text "Hello world!" via `helloWorldReader` in the
34
- // zip, and closes the writer.
94
+ // "hello.txt" containing the text "Hello world!" via `helloWorldReader`, and
95
+ // closes the writer.
35
96
  const zipWriter = new ZipWriter(zipFileWriter);
36
97
  await zipWriter.add("hello.txt", helloWorldReader);
37
98
  await zipWriter.close();
@@ -39,22 +100,14 @@ await zipWriter.close();
39
100
  // Retrieves the Blob object containing the zip content into `zipFileBlob`.
40
101
  const zipFileBlob = await zipFileBlobPromise;
41
102
 
42
- // Uncomment the following code to download the zip file (in a browser)
43
- //
44
- // const anchorElement = document.createElement("a");
45
- // anchorElement.href = URL.createObjectURL(zipFileBlob);
46
- // anchorElement.download = "hello.zip";
47
- // anchorElement.click();
48
- //
49
-
50
103
  // ----
51
104
  // Read the zip file
52
105
  // ----
53
106
 
54
107
  // Creates a BlobReader object used to read `zipFileBlob`.
55
108
  const zipFileReader = new BlobReader(zipFileBlob);
56
- // Creates a TransformStream object where the content of the first entry in the
57
- // zip will be written in the `writable` property.
109
+ // Creates a TransformStream object, the content of the first entry in the zip
110
+ // will be written in the `writable` property.
58
111
  const helloWorldWriter = new TransformStream();
59
112
  // Creates a Promise object resolved to the content of the first entry returned
60
113
  // as text via the `readable` property of `helloWorldWriter`.
package/dist/README.md CHANGED
@@ -1,8 +1,10 @@
1
1
  # Built scripts of zip.js
2
-
2
+
3
+ **Warning**: These files are not compatible with ES modules, i.e. they cannot be imported with `import`. Instead, import `index.js` in the root folder of the project or one of the files prefixed with `zip-` in the [`/lib`](../lib) folder (e.g. `/lib/zip-no-worker-inflate.js`).
4
+
3
5
  - for production (minified):
4
6
 
5
- | | [`ZipReader`](https://gildas-lormeau.github.io/zip.js/core-api.html#zip-reading) API | [`ZipWriter`](https://gildas-lormeau.github.io/zip.js/core-api.html#zip-writing) API | [`zip.fs`](https://gildas-lormeau.github.io/zip.js/fs-api.html#fs-constructor) API | Web Workers | No Web Workers | Usage |
7
+ | | [`ZipReader`](https://gildas-lormeau.github.io/zip.js/api/classes/ZipReader.html) API | [`ZipWriter`](https://gildas-lormeau.github.io/zip.js/api/classes/ZipWriter.html) API | [`zip.fs`](https://gildas-lormeau.github.io/zip.js/api/classes/FS.html) API | Web Workers | No Web Workers | Usage |
6
8
  |--------------------------------|-----------------|-----------------|--------------|-------------|----------------|-------------------------------------------------------|
7
9
  | `zip.min.js` | x | x | | x | | compression/decompression with web workers |
8
10
  | `zip-no-worker.min.js` | x | x | | | x | compression/decompression without web workers |
@@ -14,13 +16,13 @@
14
16
 
15
17
  - for development/debugging:
16
18
 
17
- | | [`zip`](https://gildas-lormeau.github.io/zip.js/core-api.html) API | [`zip.fs`](https://gildas-lormeau.github.io/zip.js/fs-api.html#fs-constructor) API | Web Workers | No Web Workers |
19
+ | | `zip` API | [`zip.fs`](https://gildas-lormeau.github.io/zip.js/api/classes/FS.html) API | Web Workers | No Web Workers |
18
20
  |-----------------------|-----------|--------------|-------------|----------------|
19
21
  | `zip.js` | x | | x | |
20
22
  | `zip-full.js` | x | | x | x |
21
23
  | `zip-fs.js` | x | x | x | |
22
24
  | `zip-fs-full.js` | x | x | x | x |
23
25
 
24
- - `z-worker.js` can be used as a web worker script if the [CSP](https://developer.mozilla.org/docs/Web/HTTP/CSP) does not allow to load it with a Blob URI
26
+ - `z-worker.js` can be used as a web worker script if the [Content Security Policy](https://developer.mozilla.org/docs/Web/HTTP/CSP) blocks scripts loaded with a `blob:` scheme
25
27
  - `z-worker-fflate.js` is the web worker script for using [fflate](https://gildas-lormeau.github.io/zip.js/core-api.html#alternative-codec-fflate)
26
28
  - `z-worker-pako.js` is the web worker script for using [pako](https://gildas-lormeau.github.io/zip.js/core-api.html#alternative-codec-pako)
@@ -7951,18 +7951,19 @@
7951
7951
 
7952
7952
  class Uint8ArrayWriter extends Writer {
7953
7953
 
7954
- constructor() {
7955
- super();
7956
- this.array = new Uint8Array();
7954
+ init(initSize = 0) {
7955
+ this.array = new Uint8Array(initSize);
7957
7956
  }
7958
7957
 
7959
7958
  writeUint8Array(array) {
7960
- super.writeUint8Array(array);
7961
7959
  const writer = this;
7962
- const previousArray = writer.array;
7963
- writer.array = new Uint8Array(previousArray.length + array.length);
7964
- writer.array.set(previousArray);
7965
- writer.array.set(array, previousArray.length);
7960
+ if (writer.size + array.length > writer.array.length) {
7961
+ const previousArray = writer.array;
7962
+ writer.array = new Uint8Array(previousArray.length + array.length);
7963
+ writer.array.set(previousArray);
7964
+ }
7965
+ writer.array.set(array, writer.size);
7966
+ super.writeUint8Array(array);
7966
7967
  }
7967
7968
 
7968
7969
  getData() {
@@ -7976,9 +7977,9 @@
7976
7977
  return protocol == "http:" || protocol == "https:";
7977
7978
  }
7978
7979
 
7979
- async function initStream(stream) {
7980
+ async function initStream(stream, initSize) {
7980
7981
  if (stream.init && !stream.initialized) {
7981
- await stream.init();
7982
+ await stream.init(initSize);
7982
7983
  }
7983
7984
  }
7984
7985
 
@@ -8397,6 +8398,7 @@
8397
8398
  bitFlag,
8398
8399
  signature,
8399
8400
  rawLastModDate,
8401
+ uncompressedSize,
8400
8402
  compressedSize
8401
8403
  } = zipEntry;
8402
8404
  const localDirectory = zipEntry.localDirectory = {};
@@ -8437,7 +8439,7 @@
8437
8439
  readable.size = size;
8438
8440
  const { writable } = writer;
8439
8441
  const signal = getOptionValue$1(zipEntry, options, "signal");
8440
- await initStream(writer);
8442
+ await initStream(writer, uncompressedSize);
8441
8443
  const { onstart, onprogress, onend } = options;
8442
8444
  const workerOptions = {
8443
8445
  options: {
@@ -8765,6 +8767,7 @@
8765
8767
  const EXTRAFIELD_LENGTH_ZIP64 = 24;
8766
8768
 
8767
8769
  let workers = 0;
8770
+ const pendingEntries = [];
8768
8771
 
8769
8772
  class ZipWriter {
8770
8773
 
@@ -8777,7 +8780,6 @@
8777
8780
  filenames: new Set(),
8778
8781
  offset: writer.size || 0,
8779
8782
  pendingCompressedSize: 0,
8780
- pendingEntries: [],
8781
8783
  pendingAddFileCalls: new Set()
8782
8784
  });
8783
8785
  }
@@ -8786,36 +8788,34 @@
8786
8788
  const zipWriter = this;
8787
8789
  const {
8788
8790
  pendingAddFileCalls,
8789
- pendingEntries,
8790
8791
  config
8791
8792
  } = zipWriter;
8792
8793
  if (workers < config.maxWorkers) {
8793
8794
  workers++;
8794
- let promiseAddFile;
8795
- try {
8796
- name = name.trim();
8797
- if (zipWriter.filenames.has(name)) {
8798
- throw new Error(ERR_DUPLICATED_NAME);
8799
- }
8800
- zipWriter.filenames.add(name);
8801
- promiseAddFile = addFile(zipWriter, name, reader, options);
8802
- pendingAddFileCalls.add(promiseAddFile);
8803
- return await promiseAddFile;
8804
- } catch (error) {
8805
- zipWriter.filenames.delete(name);
8806
- throw error;
8807
- } finally {
8808
- pendingAddFileCalls.delete(promiseAddFile);
8795
+ } else {
8796
+ await new Promise(resolve => pendingEntries.push(resolve));
8797
+ }
8798
+ let promiseAddFile;
8799
+ try {
8800
+ name = name.trim();
8801
+ if (zipWriter.filenames.has(name)) {
8802
+ throw new Error(ERR_DUPLICATED_NAME);
8803
+ }
8804
+ zipWriter.filenames.add(name);
8805
+ promiseAddFile = addFile(zipWriter, name, reader, options);
8806
+ pendingAddFileCalls.add(promiseAddFile);
8807
+ return await promiseAddFile;
8808
+ } catch (error) {
8809
+ zipWriter.filenames.delete(name);
8810
+ throw error;
8811
+ } finally {
8812
+ pendingAddFileCalls.delete(promiseAddFile);
8813
+ const pendingEntry = pendingEntries.shift();
8814
+ if (pendingEntry) {
8815
+ pendingEntry();
8816
+ } else {
8809
8817
  workers--;
8810
- const pendingEntry = pendingEntries.shift();
8811
- if (pendingEntry) {
8812
- zipWriter.add(pendingEntry.name, pendingEntry.reader, pendingEntry.options)
8813
- .then(pendingEntry.resolve)
8814
- .catch(pendingEntry.reject);
8815
- }
8816
8818
  }
8817
- } else {
8818
- return new Promise((resolve, reject) => pendingEntries.push({ name, reader, options, resolve, reject }));
8819
8819
  }
8820
8820
  }
8821
8821
 
@@ -8985,8 +8985,9 @@
8985
8985
  let bufferedWrite;
8986
8986
  let releaseLockWriter;
8987
8987
  let releaseLockCurrentFileEntry;
8988
- let bufferedDataWritten;
8988
+ let writingBufferedData;
8989
8989
  let fileWriter;
8990
+ let fileWriterSize;
8990
8991
  files.set(name, fileEntry);
8991
8992
  try {
8992
8993
  let lockPreviousFileEntry;
@@ -9003,6 +9004,7 @@
9003
9004
  await initStream(writer);
9004
9005
  fileWriter = writer;
9005
9006
  }
9007
+ fileWriterSize = fileWriter.size;
9006
9008
  fileEntry = await createFileEntry(reader, fileEntry, fileWriter.writable, zipWriter.config, options);
9007
9009
  files.set(name, fileEntry);
9008
9010
  fileEntry.filename = name;
@@ -9010,7 +9012,7 @@
9010
9012
  let blob = fileWriter.getData();
9011
9013
  await lockPreviousFileEntry;
9012
9014
  await requestLockWriter();
9013
- bufferedDataWritten = true;
9015
+ writingBufferedData = true;
9014
9016
  const { writable } = writer;
9015
9017
  if (!dataDescriptor) {
9016
9018
  const headerLength = 26;
@@ -9030,7 +9032,7 @@
9030
9032
  blob = blob.slice(headerLength);
9031
9033
  }
9032
9034
  await blob.stream().pipeTo(writable, { preventClose: true, signal });
9033
- bufferedDataWritten = false;
9035
+ writingBufferedData = false;
9034
9036
  }
9035
9037
  fileEntry.offset = zipWriter.offset;
9036
9038
  if (fileEntry.zip64) {
@@ -9042,9 +9044,12 @@
9042
9044
  zipWriter.offset += fileEntry.length;
9043
9045
  return fileEntry;
9044
9046
  } catch (error) {
9045
- if ((bufferedWrite && bufferedDataWritten) || (!bufferedWrite && fileEntry.dataWritten)) {
9046
- error.corruptedEntry = zipWriter.hasCorruptedEntries = true;
9047
- zipWriter.offset += fileWriter.size;
9047
+ if ((bufferedWrite && writingBufferedData) || (!bufferedWrite && fileEntry.writingData)) {
9048
+ zipWriter.hasCorruptedEntries = true;
9049
+ if (error) {
9050
+ error.corruptedEntry = true;
9051
+ }
9052
+ zipWriter.offset += fileWriter.size - fileWriterSize;
9048
9053
  }
9049
9054
  files.delete(name);
9050
9055
  throw error;
@@ -9221,10 +9226,10 @@
9221
9226
  arraySet(localHeaderArray, rawExtraField, 30 + rawFilename.length + rawExtraFieldAES.length + rawExtraFieldExtendedTimestamp.length + rawExtraFieldNTFS.length);
9222
9227
  let result;
9223
9228
  let compressedSize = 0;
9229
+ fileEntry.writingData = pendingFileEntry.writingData = true;
9224
9230
  if (reader) {
9225
9231
  reader.chunkSize = getChunkSize(config);
9226
9232
  await writeData(writable, localHeaderArray);
9227
- fileEntry.dataWritten = pendingFileEntry.dataWritten = true;
9228
9233
  const size = () => reader.size;
9229
9234
  const readable = reader.readable;
9230
9235
  readable.size = size;
@@ -9251,7 +9256,6 @@
9251
9256
  compressedSize = result.size;
9252
9257
  } else {
9253
9258
  await writeData(writable, localHeaderArray);
9254
- fileEntry.dataWritten = pendingFileEntry.dataWritten = true;
9255
9259
  }
9256
9260
  let dataDescriptorArray = new Uint8Array();
9257
9261
  let dataDescriptorView, dataDescriptorOffset = 0;
@@ -9304,7 +9308,8 @@
9304
9308
  creationDate,
9305
9309
  lastAccessDate,
9306
9310
  encrypted,
9307
- length
9311
+ length,
9312
+ writingData: false
9308
9313
  });
9309
9314
  return fileEntry;
9310
9315
  }
@@ -9586,7 +9591,7 @@
9586
9591
  return zipEntry.data;
9587
9592
  } else {
9588
9593
  const reader = zipEntry.reader = new zipEntry.Reader(zipEntry.data, options);
9589
- await Promise.all([initStream(reader), initStream(writer)]);
9594
+ await Promise.all([initStream(reader), initStream(writer, zipEntry.data.uncompressedSize)]);
9590
9595
  zipEntry.uncompressedSize = reader.size;
9591
9596
  const readable = reader.readable;
9592
9597
  readable.size = () => reader.size;