@weapnl/js-junction 0.2.0 → 0.3.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/CHANGELOG.md +3 -0
- package/README.md +20 -0
- package/index.d.ts +1 -0
- package/package.json +1 -1
- package/src/api.js +15 -0
- package/src/builder/model.js +56 -7
- package/src/connection.js +4 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## v0.3.0
|
|
6
|
+
- Added `chunkUploadsBySize` option on the `Api` class to automatically chunk file uploads across multiple requests when the total size exceeds the configured size.
|
|
7
|
+
|
|
5
8
|
## v0.2.0
|
|
6
9
|
- Added `data` propery to `delete` function of a Request to allow sending json data in the delete request.
|
|
7
10
|
- Added `extraData` property to `destroy` function of a Model to allow sending extra json data in the delete request.
|
package/README.md
CHANGED
|
@@ -13,6 +13,7 @@ This package has support for Typescript (TS).
|
|
|
13
13
|
- [Performing Requests](#performing-requests)
|
|
14
14
|
- [Applying Filters and Scopes](#applying-filters-and-scopes)
|
|
15
15
|
- [Uploading Files with Spatie Medialibrary](#uploading-files-with-spatie-medialibrary)
|
|
16
|
+
- [Chunked Uploads](#chunked-uploads)
|
|
16
17
|
|
|
17
18
|
## Installation
|
|
18
19
|
```bash
|
|
@@ -439,3 +440,22 @@ employee.save();
|
|
|
439
440
|
```
|
|
440
441
|
|
|
441
442
|
In this scenario, the uploaded files are linked to the `ProfilePicture` collection within the `Contact` relationship of the `Employee` model. When the `save()` method is called, the files are properly attached within the nested structure.
|
|
443
|
+
|
|
444
|
+
### Chunked Uploads
|
|
445
|
+
|
|
446
|
+
When uploading multiple files via the `upload` method, the total combined size may exceed the server's limit, or you may want to split large batches into smaller requests. Use `chunkUploadsBySize` to split files across multiple requests automatically.
|
|
447
|
+
|
|
448
|
+
**Configuring chunk size:**
|
|
449
|
+
```js
|
|
450
|
+
api.chunkUploadsBySize(10 * 1024 * 1024); // 10 MB per request
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
**Resetting (single request for all files):**
|
|
454
|
+
```js
|
|
455
|
+
api.chunkUploadsBySize(null); // default behavior
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
**How it works:**
|
|
459
|
+
- When set, the `upload` method groups files into chunks where the total file size per chunk does not exceed the configured size.
|
|
460
|
+
- Each chunk is uploaded in a separate request; response data is combined automatically.
|
|
461
|
+
- A single file that exceeds the size on its own is sent as its own request.
|
package/index.d.ts
CHANGED
package/package.json
CHANGED
package/src/api.js
CHANGED
|
@@ -12,6 +12,7 @@ export default class Api {
|
|
|
12
12
|
this.setHeader('X-Requested-With', 'XMLHttpRequest');
|
|
13
13
|
|
|
14
14
|
this._requests = [];
|
|
15
|
+
this._chunkUploadSize = null;
|
|
15
16
|
|
|
16
17
|
this.host('/').suffix('');
|
|
17
18
|
|
|
@@ -29,6 +30,20 @@ export default class Api {
|
|
|
29
30
|
return this;
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Chunk file uploads into multiple requests when total size exceeds the given size.
|
|
35
|
+
* Useful when the API has a max upload limit, or to split large batches into smaller requests.
|
|
36
|
+
*
|
|
37
|
+
* @param {number} bytes Maximum total file size per request in bytes.
|
|
38
|
+
*
|
|
39
|
+
* @returns {this} The current instance.
|
|
40
|
+
*/
|
|
41
|
+
chunkUploadsBySize (bytes) {
|
|
42
|
+
this._chunkUploadSize = bytes;
|
|
43
|
+
|
|
44
|
+
return this;
|
|
45
|
+
}
|
|
46
|
+
|
|
32
47
|
/**
|
|
33
48
|
* @param {string} suffix
|
|
34
49
|
*
|
package/src/builder/model.js
CHANGED
|
@@ -302,20 +302,69 @@ export default class Model extends Request {
|
|
|
302
302
|
*/
|
|
303
303
|
async upload (files, collection) {
|
|
304
304
|
this._media ??= {};
|
|
305
|
-
|
|
305
|
+
files = _.flatMapDeep(Array.isArray(files) ? files : [files]).filter((value) => value instanceof File);
|
|
306
306
|
|
|
307
|
-
if (
|
|
307
|
+
if (files.length === 0) {
|
|
308
308
|
this._media[collection] = {};
|
|
309
309
|
return;
|
|
310
310
|
}
|
|
311
311
|
|
|
312
|
-
const
|
|
313
|
-
files: _.flatMapDeep(filesArray),
|
|
314
|
-
}, {}, '/media/upload');
|
|
312
|
+
const chunkSize = this._connection.getChunkUploadSize();
|
|
315
313
|
|
|
316
|
-
this.
|
|
314
|
+
const chunks = chunkSize ? this._chunkFilesBySize(files, chunkSize) : [files];
|
|
317
315
|
|
|
318
|
-
|
|
316
|
+
let allResponseData = [];
|
|
317
|
+
|
|
318
|
+
for (const chunk of chunks) {
|
|
319
|
+
const request = await this.storeFiles({
|
|
320
|
+
files: chunk,
|
|
321
|
+
}, {}, '/media/upload');
|
|
322
|
+
|
|
323
|
+
if (request._response.data) {
|
|
324
|
+
allResponseData = allResponseData.concat(
|
|
325
|
+
_.castArray(request._response.data),
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
this._media[collection] = allResponseData;
|
|
331
|
+
|
|
332
|
+
return allResponseData;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Split files into chunks that don't exceed the given max size.
|
|
337
|
+
* A single file that exceeds the limit will still be sent as its own chunk.
|
|
338
|
+
*
|
|
339
|
+
* @param {File[]} files
|
|
340
|
+
* @param {number} maxSize Maximum total file size per chunk in bytes.
|
|
341
|
+
*
|
|
342
|
+
* @returns {File[][]} Array of file arrays (chunks).
|
|
343
|
+
* @private
|
|
344
|
+
*/
|
|
345
|
+
_chunkFilesBySize (files, maxSize) {
|
|
346
|
+
const chunks = [];
|
|
347
|
+
let currentChunk = [];
|
|
348
|
+
let currentSize = 0;
|
|
349
|
+
|
|
350
|
+
for (const file of files) {
|
|
351
|
+
const fileSize = file.size || 0;
|
|
352
|
+
|
|
353
|
+
if (currentChunk.length > 0 && currentSize + fileSize > maxSize) {
|
|
354
|
+
chunks.push(currentChunk);
|
|
355
|
+
currentChunk = [];
|
|
356
|
+
currentSize = 0;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
currentChunk.push(file);
|
|
360
|
+
currentSize += fileSize;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (currentChunk.length > 0) {
|
|
364
|
+
chunks.push(currentChunk);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
return chunks;
|
|
319
368
|
}
|
|
320
369
|
|
|
321
370
|
/**
|