@zip.js/zip.js 2.5.2 → 2.5.5

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.
Files changed (55) hide show
  1. package/dist/z-worker-fflate.js +1 -1
  2. package/dist/z-worker-pako.js +1 -1
  3. package/dist/z-worker.js +1 -1
  4. package/dist/zip-fs-full.js +460 -482
  5. package/dist/zip-fs-full.min.js +1 -1
  6. package/dist/zip-fs.js +460 -482
  7. package/dist/zip-fs.min.js +1 -1
  8. package/dist/zip-full.js +460 -482
  9. package/dist/zip-full.min.js +1 -1
  10. package/dist/zip-no-worker-deflate.min.js +1 -1
  11. package/dist/zip-no-worker-inflate.min.js +1 -1
  12. package/dist/zip-no-worker.min.js +1 -1
  13. package/dist/zip.js +460 -482
  14. package/dist/zip.min.js +1 -1
  15. package/index-fflate.js +1 -1
  16. package/index.d.ts +1 -1
  17. package/index.js +3 -3
  18. package/lib/core/codec-interface.js +89 -0
  19. package/lib/core/{codecs/codec-pool-worker.js → codec-pool-worker.js} +55 -29
  20. package/lib/core/{codecs/codec-pool.js → codec-pool.js} +28 -9
  21. package/lib/core/configuration.js +10 -1
  22. package/lib/core/io.js +102 -100
  23. package/lib/core/{codecs → streams}/aes-crypto-stream.js +68 -54
  24. package/lib/core/{codecs → streams}/codec-stream.js +3 -6
  25. package/lib/core/{codecs → streams/codecs}/crc32.js +0 -0
  26. package/lib/core/{codecs → streams/codecs}/deflate.js +0 -0
  27. package/lib/core/{codecs → streams/codecs}/inflate.js +0 -0
  28. package/lib/core/{codecs → streams/codecs}/sjcl.js +0 -0
  29. package/lib/core/{codecs → streams}/crc32-stream.js +3 -4
  30. package/lib/core/{codecs → streams}/zip-crypto-stream.js +28 -32
  31. package/lib/core/streams/zip-entry-stream.js +178 -0
  32. package/lib/core/z-worker-core.js +30 -15
  33. package/lib/core/zip-fs-core.js +1 -1
  34. package/lib/core/zip-reader.js +21 -12
  35. package/lib/core/zip-writer.js +33 -22
  36. package/lib/z-worker-fflate.js +4 -1
  37. package/lib/z-worker-inline.js +1 -1
  38. package/lib/z-worker.js +2 -2
  39. package/lib/zip-fflate-shim.js +4 -1
  40. package/lib/zip-fs.js +6 -2
  41. package/lib/zip-full-fflate.js +6 -3
  42. package/lib/zip-full.js +8 -5
  43. package/lib/zip-no-worker-deflate.js +7 -3
  44. package/lib/zip-no-worker-fflate-deflate.js +6 -2
  45. package/lib/zip-no-worker-fflate-inflate.js +6 -3
  46. package/lib/zip-no-worker-fflate.js +6 -3
  47. package/lib/zip-no-worker-inflate.js +7 -4
  48. package/lib/zip-no-worker.js +8 -5
  49. package/lib/zip.js +6 -3
  50. package/package.json +2 -8
  51. package/tests/all/test-safe-closing.js +1 -1
  52. package/tests/node/package.json +2 -6
  53. package/tests/node/test-node.js +7 -11
  54. package/lib/core/codecs/codec.js +0 -230
  55. package/lib/core/engine.js +0 -89
@@ -26,9 +26,17 @@
26
26
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
27
  */
28
28
 
29
- /* global Worker, URL */
30
-
31
- import { createCodec, MESSAGE_EVENT_TYPE, MESSAGE_START, MESSAGE_PULL, MESSAGE_DATA, MESSAGE_ABORT } from "./codec.js";
29
+ /* global Worker, URL, TransformStream */
30
+
31
+ import {
32
+ createCodec,
33
+ MESSAGE_EVENT_TYPE,
34
+ MESSAGE_START,
35
+ MESSAGE_PULL,
36
+ MESSAGE_DATA,
37
+ MESSAGE_ABORT,
38
+ MESSAGE_CLOSE
39
+ } from "./codec-interface.js";
32
40
 
33
41
  let classicWorkersSupported = true;
34
42
 
@@ -36,10 +44,12 @@ export {
36
44
  getWorker
37
45
  };
38
46
 
39
- function getWorker(workerData, codecConstructor, options, config, onTaskFinished, webWorker, scripts) {
47
+ function getWorker(workerData, codecConstructor, readable, writable, options, config, streamOptions, onTaskFinished, webWorker, scripts) {
40
48
  Object.assign(workerData, {
41
49
  busy: true,
42
50
  codecConstructor,
51
+ readable,
52
+ writable,
43
53
  options: Object.assign({}, options),
44
54
  scripts,
45
55
  terminate() {
@@ -53,27 +63,50 @@ function getWorker(workerData, codecConstructor, options, config, onTaskFinished
53
63
  onTaskFinished(workerData);
54
64
  }
55
65
  });
66
+ const { signal, onprogress, size } = streamOptions;
67
+ if (signal || onprogress) {
68
+ let chunkOffset = 0;
69
+ const transformer = {};
70
+ if (onprogress) {
71
+ transformer.transform = (chunk, controller) => {
72
+ chunkOffset += chunk.length;
73
+ try {
74
+ onprogress(chunkOffset, size());
75
+ } catch (_error) {
76
+ // ignored
77
+ }
78
+ controller.enqueue(chunk);
79
+ };
80
+ }
81
+ workerData.readable = readable.pipeThrough(new TransformStream(transformer), { signal });
82
+ }
56
83
  return webWorker ? createWebWorkerInterface(workerData, config) : createWorkerInterface(workerData, config);
57
84
  }
58
85
 
59
86
  function createWorkerInterface(workerData, config) {
60
- const interfaceCodec = createCodec(workerData.codecConstructor, workerData.options, config);
87
+ const interfaceCodec = createCodec(workerData.codecConstructor, workerData.readable, workerData.writable, workerData.options, config);
61
88
  const codec = {
62
89
  abort() {
63
90
  interfaceCodec.abort();
64
91
  workerData.onTaskFinished();
65
92
  },
66
- start() {
67
- return interfaceCodec.start();
93
+ run() {
94
+ const result = interfaceCodec.run();
95
+ workerData.onTaskFinished();
96
+ return result;
68
97
  }
69
98
  };
70
- interfaceCodec.pull = () => codec.pull();
71
- interfaceCodec.ondata = data => ondata(workerData, codec, data);
72
99
  return codec;
73
100
  }
74
101
 
75
102
  function createWebWorkerInterface(workerData, { baseURL, chunkSize }) {
76
103
  const workerOptions = { type: "module" };
104
+ workerData.reader = workerData.readable.getReader();
105
+ workerData.writer = workerData.writable.getWriter();
106
+ workerData.result = new Promise((resolve, reject) => {
107
+ workerData.resolveResult = resolve;
108
+ workerData.rejectResult = reject;
109
+ });
77
110
  if (!workerData.interface) {
78
111
  if (!classicWorkersSupported) {
79
112
  workerData.worker = getWorker(workerOptions);
@@ -91,10 +124,11 @@ function createWebWorkerInterface(workerData, { baseURL, chunkSize }) {
91
124
  sendMessage({ type: MESSAGE_ABORT });
92
125
  workerData.onTaskFinished();
93
126
  },
94
- start() {
127
+ run() {
95
128
  const options = workerData.options;
96
129
  const scripts = workerData.scripts.slice(1);
97
130
  sendMessage({ type: MESSAGE_START, scripts, options, config: { chunkSize } });
131
+ return workerData.result;
98
132
  }
99
133
  };
100
134
  }
@@ -136,39 +170,31 @@ function createWebWorkerInterface(workerData, { baseURL, chunkSize }) {
136
170
  async function onMessage(event) {
137
171
  const message = event.data;
138
172
  const reponseError = message.error;
139
- const codec = workerData.interface;
140
173
  try {
141
174
  if (reponseError) {
142
175
  const error = new Error(reponseError.message);
143
176
  error.stack = reponseError.stack;
144
- codec.onerror(error);
177
+ workerData.rejectResult(error);
145
178
  workerData.onTaskFinished();
146
179
  } else {
147
180
  if (message.type == MESSAGE_PULL) {
148
- const { value, done } = await codec.pull();
181
+ const { value, done } = await workerData.reader.read();
149
182
  sendMessage({ type: MESSAGE_DATA, data: value, done, messageId: message.messageId });
150
183
  }
151
184
  if (message.type == MESSAGE_DATA) {
152
- const { value } = message.data;
153
- if (value && value.data) {
154
- value.data = new Uint8Array(value.data);
155
- }
156
- await ondata(workerData, codec, message.data);
185
+ let { data } = message;
186
+ data = new Uint8Array(data);
187
+ await workerData.writer.ready;
188
+ workerData.writer.write(data);
189
+ }
190
+ if (message.type == MESSAGE_CLOSE) {
191
+ workerData.resolveResult(message.result);
192
+ workerData.onTaskFinished();
157
193
  }
158
194
  }
159
195
  } catch (error) {
160
- codec.onerror(error);
196
+ workerData.rejectResult(error);
161
197
  workerData.onTaskFinished();
162
198
  }
163
199
  }
164
- }
165
-
166
- async function ondata(workerData, codec, data) {
167
- let { value, done } = data;
168
- if (done) {
169
- await codec.ondata({ value: { data: value.data, signature: value.signature }, done });
170
- workerData.onTaskFinished();
171
- } else if (value.data) {
172
- await codec.ondata({ value: { data: value.data } });
173
- }
174
200
  }
@@ -28,47 +28,66 @@
28
28
 
29
29
  /* global setTimeout, clearTimeout */
30
30
 
31
- import { CODEC_INFLATE, CODEC_DEFLATE, ERR_INVALID_SIGNATURE, ERR_INVALID_PASSWORD } from "./codec.js";
31
+ import {
32
+ CODEC_INFLATE,
33
+ CODEC_DEFLATE,
34
+ ERR_INVALID_SIGNATURE,
35
+ ERR_INVALID_PASSWORD,
36
+ ERR_ABORT
37
+ } from "./codec-interface.js";
32
38
  import { getWorker } from "./codec-pool-worker.js";
33
39
 
34
40
  let pool = [];
35
41
  const pendingRequests = [];
36
42
 
37
43
  export {
38
- createCodec,
44
+ runCodec,
39
45
  terminateWorkers,
40
46
  CODEC_DEFLATE,
41
47
  CODEC_INFLATE,
42
48
  ERR_INVALID_SIGNATURE,
43
- ERR_INVALID_PASSWORD
49
+ ERR_INVALID_PASSWORD,
50
+ ERR_ABORT
44
51
  };
45
52
 
46
53
  let indexWorker = 0;
47
54
 
48
- function createCodec(codecConstructor, options, config) {
55
+ async function runCodec(codecConstructor, readable, writable, options, config, streamOptions) {
49
56
  const streamCopy = !options.compressed && !options.signed && !options.encrypted;
50
57
  const webWorker = !streamCopy && (options.useWebWorkers || (options.useWebWorkers === undefined && config.useWebWorkers));
51
58
  const scripts = webWorker && config.workerScripts ? config.workerScripts[options.codecType] : [];
52
59
  options.useCompressionStream = options.useCompressionStream === undefined ? config.useCompressionStream : options.useCompressionStream;
60
+ let codec;
53
61
  if (pool.length < config.maxWorkers) {
54
62
  const workerData = { indexWorker };
55
63
  indexWorker++;
56
64
  pool.push(workerData);
57
- return getWorker(workerData, codecConstructor, options, config, onTaskFinished, webWorker, scripts);
65
+ codec = getWorker(workerData, codecConstructor, readable, writable, options, config, streamOptions, onTaskFinished, webWorker, scripts);
58
66
  } else {
59
67
  const workerData = pool.find(workerData => !workerData.busy);
60
68
  if (workerData) {
61
69
  clearTerminateTimeout(workerData);
62
- return getWorker(workerData, codecConstructor, options, config, onTaskFinished, webWorker, scripts);
70
+ codec = getWorker(workerData, codecConstructor, readable, writable, options, config, streamOptions, onTaskFinished, webWorker, scripts);
71
+ } else {
72
+ codec = await new Promise(resolve => pendingRequests.push({ resolve, codecConstructor, readable, writable, options, webWorker, scripts }));
73
+ }
74
+ }
75
+ const { signal } = streamOptions;
76
+ try {
77
+ return await codec.run(signal);
78
+ } catch (error) {
79
+ if (signal && signal.aborted && signal.reason == error) {
80
+ codec.abort();
81
+ throw new Error(ERR_ABORT);
63
82
  } else {
64
- return new Promise(resolve => pendingRequests.push({ resolve, codecConstructor, options, webWorker, scripts }));
83
+ throw error;
65
84
  }
66
85
  }
67
86
 
68
87
  function onTaskFinished(workerData) {
69
88
  if (pendingRequests.length) {
70
- const [{ resolve, codecConstructor, options, webWorker, scripts }] = pendingRequests.splice(0, 1);
71
- resolve(getWorker(workerData, codecConstructor, options, config, onTaskFinished, webWorker, scripts));
89
+ const [{ resolve, codecConstructor, readable, writable, options, webWorker, scripts }] = pendingRequests.splice(0, 1);
90
+ resolve(getWorker(workerData, codecConstructor, readable, writable, options, config, streamOptions, onTaskFinished, webWorker, scripts));
72
91
  } else if (workerData.worker) {
73
92
  clearTerminateTimeout(workerData);
74
93
  if (Number.isFinite(config.terminateWorkerTimeout) && config.terminateWorkerTimeout >= 0) {
@@ -28,6 +28,7 @@
28
28
 
29
29
  /* global navigator */
30
30
 
31
+ const MINIMUM_CHUNK_SIZE = 64;
31
32
  const DEFAULT_CONFIGURATION = {
32
33
  chunkSize: 512 * 1024,
33
34
  maxWorkers: (typeof navigator != "undefined" && navigator.hardwareConcurrency) || 2,
@@ -40,13 +41,18 @@ const config = Object.assign({}, DEFAULT_CONFIGURATION);
40
41
 
41
42
  export {
42
43
  configure,
43
- getConfiguration
44
+ getConfiguration,
45
+ getChunkSize
44
46
  };
45
47
 
46
48
  function getConfiguration() {
47
49
  return config;
48
50
  }
49
51
 
52
+ function getChunkSize(config) {
53
+ return Math.max(config.chunkSize, MINIMUM_CHUNK_SIZE);
54
+ }
55
+
50
56
  function configure(configuration) {
51
57
  if (configuration.baseURL !== undefined) {
52
58
  config.baseURL = configuration.baseURL;
@@ -60,6 +66,9 @@ function configure(configuration) {
60
66
  if (configuration.terminateWorkerTimeout !== undefined) {
61
67
  config.terminateWorkerTimeout = configuration.terminateWorkerTimeout;
62
68
  }
69
+ if (configuration.useCompressionStream !== undefined) {
70
+ config.useCompressionStream = configuration.useCompressionStream;
71
+ }
63
72
  if (configuration.useWebWorkers !== undefined) {
64
73
  config.useWebWorkers = configuration.useWebWorkers;
65
74
  }
package/lib/core/io.js CHANGED
@@ -26,7 +26,7 @@
26
26
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
27
  */
28
28
 
29
- /* global Blob, FileReader, atob, btoa, XMLHttpRequest, document, fetch */
29
+ /* global Blob, FileReader, atob, btoa, XMLHttpRequest, document, fetch, ReadableStream, WritableStream */
30
30
 
31
31
  const ERR_HTTP_STATUS = "HTTP error ";
32
32
  const ERR_HTTP_RANGE = "HTTP Range not supported";
@@ -40,6 +40,7 @@ const HTTP_HEADER_RANGE = "Range";
40
40
  const HTTP_METHOD_HEAD = "HEAD";
41
41
  const HTTP_METHOD_GET = "GET";
42
42
  const HTTP_RANGE_UNIT = "bytes";
43
+ const DEFAULT_CHUNK_SIZE = 64 * 1024;
43
44
 
44
45
  class Stream {
45
46
 
@@ -53,9 +54,39 @@ class Stream {
53
54
  }
54
55
 
55
56
  class Reader extends Stream {
57
+
58
+ getStream({ offset, size, chunkSize } = { offset: 0, chunkSize: DEFAULT_CHUNK_SIZE }) {
59
+ const reader = this;
60
+ return new ReadableStream({
61
+ start() {
62
+ this.chunkOffset = 0;
63
+ },
64
+ async pull(controller) {
65
+ const { chunkOffset } = this;
66
+ controller.enqueue(await reader.readUint8Array(offset + chunkOffset, Math.min(chunkSize, size() - chunkOffset)));
67
+ if (chunkOffset + chunkSize > size()) {
68
+ controller.close();
69
+ } else {
70
+ this.chunkOffset += chunkSize;
71
+ }
72
+ }
73
+ });
74
+ }
75
+ }
76
+
77
+ class WriterStream extends Stream {
78
+
79
+ getStream() {
80
+ const writer = this;
81
+ return new WritableStream({
82
+ write(chunk) {
83
+ return writer.writeUint8Array(chunk);
84
+ }
85
+ });
86
+ }
56
87
  }
57
88
 
58
- class Writer extends Stream {
89
+ class Writer extends WriterStream {
59
90
 
60
91
  writeUint8Array(array) {
61
92
  this.size += array.length;
@@ -70,9 +101,10 @@ class TextReader extends Reader {
70
101
  }
71
102
 
72
103
  init() {
104
+ const reader = this;
73
105
  super.init();
74
- this.blobReader.init();
75
- this.size = this.blobReader.size;
106
+ reader.blobReader.init();
107
+ reader.size = reader.blobReader.size;
76
108
  }
77
109
 
78
110
  readUint8Array(offset, length) {
@@ -94,14 +126,15 @@ class TextWriter extends Writer {
94
126
  }
95
127
 
96
128
  getData() {
97
- if (this.blob.text) {
98
- return this.blob.text();
129
+ const writer = this;
130
+ if (writer.blob.text) {
131
+ return writer.blob.text();
99
132
  } else {
100
133
  const reader = new FileReader();
101
134
  return new Promise((resolve, reject) => {
102
135
  reader.onload = event => resolve(event.target.result);
103
136
  reader.onerror = () => reject(reader.error);
104
- reader.readAsText(this.blob, this.encoding);
137
+ reader.readAsText(writer.blob, writer.encoding);
105
138
  });
106
139
  }
107
140
  }
@@ -111,19 +144,21 @@ class Data64URIReader extends Reader {
111
144
 
112
145
  constructor(dataURI) {
113
146
  super();
114
- this.dataURI = dataURI;
147
+ const reader = this;
148
+ reader.dataURI = dataURI;
115
149
  let dataEnd = dataURI.length;
116
150
  while (dataURI.charAt(dataEnd - 1) == "=") {
117
151
  dataEnd--;
118
152
  }
119
- this.dataStart = dataURI.indexOf(",") + 1;
120
- this.size = Math.floor((dataEnd - this.dataStart) * 0.75);
153
+ reader.dataStart = dataURI.indexOf(",") + 1;
154
+ reader.size = Math.floor((dataEnd - reader.dataStart) * 0.75);
121
155
  }
122
156
 
123
157
  readUint8Array(offset, length) {
124
158
  const dataArray = new Uint8Array(length);
125
159
  const start = Math.floor(offset / 3) * 4;
126
- const bytes = atob(this.dataURI.substring(start + this.dataStart, Math.ceil((offset + length) / 3) * 4 + this.dataStart));
160
+ const dataStart = this.dataStart;
161
+ const bytes = atob(this.dataURI.substring(start + dataStart, Math.ceil((offset + length) / 3) * 4 + dataStart));
127
162
  const delta = offset - Math.floor(start / 4) * 3;
128
163
  for (let indexByte = delta; indexByte < delta + length; indexByte++) {
129
164
  dataArray[indexByte - delta] = bytes.charCodeAt(indexByte);
@@ -142,20 +177,21 @@ class Data64URIWriter extends Writer {
142
177
 
143
178
  writeUint8Array(array) {
144
179
  super.writeUint8Array(array);
180
+ const writer = this;
145
181
  let indexArray = 0;
146
- let dataString = this.pending;
147
- const delta = this.pending.length;
148
- this.pending = "";
182
+ let dataString = writer.pending;
183
+ const delta = writer.pending.length;
184
+ writer.pending = "";
149
185
  for (indexArray = 0; indexArray < (Math.floor((delta + array.length) / 3) * 3) - delta; indexArray++) {
150
186
  dataString += String.fromCharCode(array[indexArray]);
151
187
  }
152
188
  for (; indexArray < array.length; indexArray++) {
153
- this.pending += String.fromCharCode(array[indexArray]);
189
+ writer.pending += String.fromCharCode(array[indexArray]);
154
190
  }
155
191
  if (dataString.length > 2) {
156
- this.data += btoa(dataString);
192
+ writer.data += btoa(dataString);
157
193
  } else {
158
- this.pending = dataString;
194
+ writer.pending = dataString;
159
195
  }
160
196
  }
161
197
 
@@ -173,14 +209,15 @@ class BlobReader extends Reader {
173
209
  }
174
210
 
175
211
  async readUint8Array(offset, length) {
176
- if (this.blob.arrayBuffer) {
177
- return new Uint8Array(await this.blob.slice(offset, offset + length).arrayBuffer());
212
+ const reader = this;
213
+ if (reader.blob.arrayBuffer) {
214
+ return new Uint8Array(await reader.blob.slice(offset, offset + length).arrayBuffer());
178
215
  } else {
179
216
  const reader = new FileReader();
180
217
  return new Promise((resolve, reject) => {
181
218
  reader.onload = event => resolve(new Uint8Array(event.target.result));
182
219
  reader.onerror = () => reject(reader.error);
183
- reader.readAsArrayBuffer(this.blob.slice(offset, offset + length));
220
+ reader.readAsArrayBuffer(reader.blob.slice(offset, offset + length));
184
221
  });
185
222
  }
186
223
  }
@@ -197,21 +234,23 @@ class BlobWriter extends Writer {
197
234
 
198
235
  writeUint8Array(array) {
199
236
  super.writeUint8Array(array);
200
- if (this.arrayBuffers.length == this.arrayBuffersMaxlength) {
201
- flushArrayBuffers(this);
237
+ const writer = this;
238
+ if (writer.arrayBuffers.length == writer.arrayBuffersMaxlength) {
239
+ flushArrayBuffers(writer);
202
240
  }
203
- this.arrayBuffers.push(array.buffer);
241
+ writer.arrayBuffers.push(array.buffer);
204
242
  }
205
243
 
206
244
  getData() {
207
- if (!this.blob) {
208
- if (this.arrayBuffers.length) {
209
- flushArrayBuffers(this);
245
+ const writer = this;
246
+ if (!writer.blob) {
247
+ if (writer.arrayBuffers.length) {
248
+ flushArrayBuffers(writer);
210
249
  }
211
- this.blob = this.pendingBlob;
212
- initArrayBuffers(this);
250
+ writer.blob = writer.pendingBlob;
251
+ initArrayBuffers(writer);
213
252
  }
214
- return this.blob;
253
+ return writer.blob;
215
254
  }
216
255
  }
217
256
 
@@ -229,78 +268,38 @@ class ReadableStreamReader {
229
268
 
230
269
  constructor(readableStream) {
231
270
  this.readableStream = readableStream;
232
- this.reader = readableStream.getReader();
233
271
  this.size = Infinity;
234
- this.index = 0;
235
- this.currentSize = 0;
236
- this.pendingValue = new Uint8Array();
237
272
  }
238
273
 
239
- init() {
274
+ init(size) {
275
+ this.size = size;
240
276
  this.initialized = true;
241
277
  }
242
278
 
243
- async readUint8Array(index, length) {
244
- if (this.index != index) {
245
- throw new Error(ERR_NOT_SEEKABLE_READER);
246
- }
247
- let data = new Uint8Array(length);
248
- let size = 0, done;
249
- do {
250
- const result = await this.reader.read();
251
- let { value } = result;
252
- done = result.done;
253
- if (value) {
254
- this.currentSize += value.length;
255
- } else {
256
- value = this.pendingValue;
257
- this.pendingValue = new Uint8Array();
258
- }
259
- if (this.pendingValue.length) {
260
- const newValue = new Uint8Array(this.pendingValue.length + value.length);
261
- newValue.set(this.pendingValue);
262
- newValue.set(value, this.pendingValue.length);
263
- this.pendingValue = new Uint8Array();
264
- value = newValue;
265
- }
266
- if (size + value.length > length) {
267
- data.set(value.subarray(0, length), size);
268
- this.pendingValue = value.subarray(length);
269
- size += length;
270
- } else {
271
- data.set(value, size);
272
- size += value.length;
273
- }
274
- } while (size < length && !done);
275
- if (done && this.size == Infinity) {
276
- this.size = this.currentSize;
277
- }
278
- if (this.size < length) {
279
- data = data.slice(0, this.size);
280
- length = this.size;
281
- }
282
- this.index += length;
283
- return data;
279
+ getStream() {
280
+ return this.readableStream;
284
281
  }
285
282
  }
286
283
 
287
284
  class WritableStreamWriter extends Writer {
288
285
 
289
- constructor(writableStream) {
286
+ constructor(writable) {
290
287
  super();
291
- this.writableStream = writableStream;
292
- this.writer = writableStream.getWriter();
288
+ const writer = this;
289
+ writer.writable = writable;
293
290
  }
294
291
 
295
292
  async writeUint8Array(array) {
296
293
  await this.writer.ready;
297
- return this.writer.write(array);
294
+ return this.writable.getWriter().write(array);
295
+ }
296
+
297
+ getStream() {
298
+ return this.writable;
298
299
  }
299
300
 
300
301
  async getData() {
301
- await this.writer.ready;
302
- await this.writer.close();
303
- return this.writableStream;
302
+ return this.writable;
304
303
  }
305
304
  }
306
305
 
@@ -308,15 +307,16 @@ class FetchReader extends Reader {
308
307
 
309
308
  constructor(url, options) {
310
309
  super();
311
- this.url = url;
312
- this.preventHeadRequest = options.preventHeadRequest;
313
- this.useRangeHeader = options.useRangeHeader;
314
- this.forceRangeRequests = options.forceRangeRequests;
315
- this.options = Object.assign({}, options);
316
- delete this.options.preventHeadRequest;
317
- delete this.options.useRangeHeader;
318
- delete this.options.forceRangeRequests;
319
- delete this.options.useXHR;
310
+ const reader = this;
311
+ reader.url = url;
312
+ reader.preventHeadRequest = options.preventHeadRequest;
313
+ reader.useRangeHeader = options.useRangeHeader;
314
+ reader.forceRangeRequests = options.forceRangeRequests;
315
+ reader.options = Object.assign({}, options);
316
+ delete reader.options.preventHeadRequest;
317
+ delete reader.options.useRangeHeader;
318
+ delete reader.options.forceRangeRequests;
319
+ delete reader.options.useXHR;
320
320
  }
321
321
 
322
322
  async init() {
@@ -333,11 +333,12 @@ class XHRReader extends Reader {
333
333
 
334
334
  constructor(url, options) {
335
335
  super();
336
- this.url = url;
337
- this.preventHeadRequest = options.preventHeadRequest;
338
- this.useRangeHeader = options.useRangeHeader;
339
- this.forceRangeRequests = options.forceRangeRequests;
340
- this.options = options;
336
+ const reader = this;
337
+ reader.url = url;
338
+ reader.preventHeadRequest = options.preventHeadRequest;
339
+ reader.useRangeHeader = options.useRangeHeader;
340
+ reader.forceRangeRequests = options.forceRangeRequests;
341
+ reader.options = options;
341
342
  }
342
343
 
343
344
  async init() {
@@ -540,10 +541,11 @@ class Uint8ArrayWriter extends Writer {
540
541
 
541
542
  writeUint8Array(array) {
542
543
  super.writeUint8Array(array);
543
- const previousArray = this.array;
544
- this.array = new Uint8Array(previousArray.length + array.length);
545
- this.array.set(previousArray);
546
- this.array.set(array, previousArray.length);
544
+ const writer = this;
545
+ const previousArray = writer.array;
546
+ writer.array = new Uint8Array(previousArray.length + array.length);
547
+ writer.array.set(previousArray);
548
+ writer.array.set(array, previousArray.length);
547
549
  }
548
550
 
549
551
  getData() {