@atlaskit/media-client 16.0.1 → 17.0.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 +21 -0
- package/dist/cjs/client/media-store/index.js +35 -16
- package/dist/cjs/constants.js +11 -2
- package/dist/cjs/models/media.js +10 -2
- package/dist/cjs/uploader/calculateChunkSize.js +45 -0
- package/dist/cjs/uploader/error.js +67 -0
- package/dist/cjs/{uploader.js → uploader/index.js} +42 -9
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/client/media-store/index.js +16 -2
- package/dist/es2019/constants.js +5 -1
- package/dist/es2019/models/media.js +8 -1
- package/dist/es2019/uploader/calculateChunkSize.js +32 -0
- package/dist/es2019/uploader/error.js +30 -0
- package/dist/es2019/{uploader.js → uploader/index.js} +39 -8
- package/dist/es2019/version.json +1 -1
- package/dist/esm/client/media-store/index.js +35 -16
- package/dist/esm/constants.js +5 -1
- package/dist/esm/models/media.js +8 -1
- package/dist/esm/uploader/calculateChunkSize.js +32 -0
- package/dist/esm/uploader/error.js +51 -0
- package/dist/esm/{uploader.js → uploader/index.js} +38 -9
- package/dist/esm/version.json +1 -1
- package/dist/types/client/media-store/index.d.ts +9 -2
- package/dist/types/constants.d.ts +3 -0
- package/dist/types/models/errors/types.d.ts +1 -1
- package/dist/types/models/media.d.ts +5 -0
- package/dist/types/uploader/calculateChunkSize.d.ts +11 -0
- package/dist/types/uploader/error.d.ts +29 -0
- package/dist/types/{uploader.d.ts → uploader/index.d.ts} +2 -2
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# @atlaskit/media-client
|
|
2
2
|
|
|
3
|
+
## 17.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- [`a718050239e`](https://bitbucket.org/atlassian/atlassian-frontend/commits/a718050239e) - Media Client Uploader enforces a hard limit of 2Tb files.
|
|
8
|
+
|
|
9
|
+
To mitigate these changes:
|
|
10
|
+
|
|
11
|
+
- Set the feature flag mediaUploadApiV2 as false or Revert to a previous version for affected consumers and methods;
|
|
12
|
+
Media Client uploadFile method.
|
|
13
|
+
Media Client File Fetcher upload method.
|
|
14
|
+
Media Picker.
|
|
15
|
+
|
|
16
|
+
- [`e4d0b89cd8b`](https://bitbucket.org/atlassian/atlassian-frontend/commits/e4d0b89cd8b) - Additional parameters and changes to the way parameters are passed to MediaStore.uploadChunk and MediaStore.probeChunks.
|
|
17
|
+
- [`d07442a7ff7`](https://bitbucket.org/atlassian/atlassian-frontend/commits/d07442a7ff7) - Breaking change to media-client uploadFile method, chunkSize and processingBatchSize as parameters removed from uploadFile.
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- [`61cf857a95a`](https://bitbucket.org/atlassian/atlassian-frontend/commits/61cf857a95a) - A util function for dynamically calculating chunkSizes.
|
|
22
|
+
- Updated dependencies
|
|
23
|
+
|
|
3
24
|
## 16.0.1
|
|
4
25
|
|
|
5
26
|
### Patch Changes
|
|
@@ -225,26 +225,38 @@ var MediaStore = /*#__PURE__*/function () {
|
|
|
225
225
|
}, {
|
|
226
226
|
key: "uploadChunk",
|
|
227
227
|
value: function () {
|
|
228
|
-
var _uploadChunk = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(etag, blob
|
|
229
|
-
var
|
|
228
|
+
var _uploadChunk = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(etag, blob) {
|
|
229
|
+
var _ref,
|
|
230
|
+
collectionName,
|
|
231
|
+
uploadId,
|
|
232
|
+
partNumber,
|
|
233
|
+
metadata,
|
|
234
|
+
options,
|
|
235
|
+
_args3 = arguments;
|
|
236
|
+
|
|
230
237
|
return _regenerator.default.wrap(function _callee3$(_context3) {
|
|
231
238
|
while (1) {
|
|
232
239
|
switch (_context3.prev = _context3.next) {
|
|
233
240
|
case 0:
|
|
241
|
+
_ref = _args3.length > 2 && _args3[2] !== undefined ? _args3[2] : {}, collectionName = _ref.collectionName, uploadId = _ref.uploadId, partNumber = _ref.partNumber;
|
|
234
242
|
metadata = {
|
|
235
243
|
method: 'PUT',
|
|
236
244
|
endpoint: '/chunk/{etag}'
|
|
237
245
|
};
|
|
238
246
|
options = _objectSpread(_objectSpread({}, metadata), {}, {
|
|
247
|
+
params: {
|
|
248
|
+
uploadId: uploadId,
|
|
249
|
+
partNumber: partNumber
|
|
250
|
+
},
|
|
239
251
|
authContext: {
|
|
240
252
|
collectionName: collectionName
|
|
241
253
|
},
|
|
242
254
|
body: blob
|
|
243
255
|
});
|
|
244
|
-
_context3.next =
|
|
256
|
+
_context3.next = 5;
|
|
245
257
|
return this.request("/chunk/".concat(etag), options);
|
|
246
258
|
|
|
247
|
-
case
|
|
259
|
+
case 5:
|
|
248
260
|
case "end":
|
|
249
261
|
return _context3.stop();
|
|
250
262
|
}
|
|
@@ -252,7 +264,7 @@ var MediaStore = /*#__PURE__*/function () {
|
|
|
252
264
|
}, _callee3, this);
|
|
253
265
|
}));
|
|
254
266
|
|
|
255
|
-
function uploadChunk(_x6, _x7
|
|
267
|
+
function uploadChunk(_x6, _x7) {
|
|
256
268
|
return _uploadChunk.apply(this, arguments);
|
|
257
269
|
}
|
|
258
270
|
|
|
@@ -260,13 +272,20 @@ var MediaStore = /*#__PURE__*/function () {
|
|
|
260
272
|
}()
|
|
261
273
|
}, {
|
|
262
274
|
key: "probeChunks",
|
|
263
|
-
value: function probeChunks(chunks
|
|
275
|
+
value: function probeChunks(chunks) {
|
|
276
|
+
var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
|
|
277
|
+
collectionName = _ref2.collectionName,
|
|
278
|
+
uploadId = _ref2.uploadId;
|
|
279
|
+
|
|
264
280
|
var metadata = {
|
|
265
281
|
method: 'POST',
|
|
266
282
|
endpoint: '/chunk/probe'
|
|
267
283
|
};
|
|
268
284
|
|
|
269
285
|
var options = _objectSpread(_objectSpread({}, metadata), {}, {
|
|
286
|
+
params: {
|
|
287
|
+
uploadId: uploadId
|
|
288
|
+
},
|
|
270
289
|
authContext: {
|
|
271
290
|
collectionName: collectionName
|
|
272
291
|
},
|
|
@@ -339,13 +358,13 @@ var MediaStore = /*#__PURE__*/function () {
|
|
|
339
358
|
key: "getFileImageURL",
|
|
340
359
|
value: function () {
|
|
341
360
|
var _getFileImageURL = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(id, params) {
|
|
342
|
-
var
|
|
361
|
+
var _ref3, collectionName, auth;
|
|
343
362
|
|
|
344
363
|
return _regenerator.default.wrap(function _callee4$(_context4) {
|
|
345
364
|
while (1) {
|
|
346
365
|
switch (_context4.prev = _context4.next) {
|
|
347
366
|
case 0:
|
|
348
|
-
|
|
367
|
+
_ref3 = params || {}, collectionName = _ref3.collection;
|
|
349
368
|
_context4.next = 3;
|
|
350
369
|
return this.resolveAuth({
|
|
351
370
|
collectionName: collectionName
|
|
@@ -363,7 +382,7 @@ var MediaStore = /*#__PURE__*/function () {
|
|
|
363
382
|
}, _callee4, this);
|
|
364
383
|
}));
|
|
365
384
|
|
|
366
|
-
function getFileImageURL(
|
|
385
|
+
function getFileImageURL(_x8, _x9) {
|
|
367
386
|
return _getFileImageURL.apply(this, arguments);
|
|
368
387
|
}
|
|
369
388
|
|
|
@@ -418,7 +437,7 @@ var MediaStore = /*#__PURE__*/function () {
|
|
|
418
437
|
}, _callee5, this);
|
|
419
438
|
}));
|
|
420
439
|
|
|
421
|
-
function getFileBinaryURL(
|
|
440
|
+
function getFileBinaryURL(_x10, _x11) {
|
|
422
441
|
return _getFileBinaryURL.apply(this, arguments);
|
|
423
442
|
}
|
|
424
443
|
|
|
@@ -467,7 +486,7 @@ var MediaStore = /*#__PURE__*/function () {
|
|
|
467
486
|
}, _callee6, this);
|
|
468
487
|
}));
|
|
469
488
|
|
|
470
|
-
function getArtifactURL(_x13, _x14
|
|
489
|
+
function getArtifactURL(_x12, _x13, _x14) {
|
|
471
490
|
return _getArtifactURL.apply(this, arguments);
|
|
472
491
|
}
|
|
473
492
|
|
|
@@ -512,7 +531,7 @@ var MediaStore = /*#__PURE__*/function () {
|
|
|
512
531
|
}, _callee7, this);
|
|
513
532
|
}));
|
|
514
533
|
|
|
515
|
-
function getImage(_x16, _x17, _x18
|
|
534
|
+
function getImage(_x15, _x16, _x17, _x18) {
|
|
516
535
|
return _getImage.apply(this, arguments);
|
|
517
536
|
}
|
|
518
537
|
|
|
@@ -557,7 +576,7 @@ var MediaStore = /*#__PURE__*/function () {
|
|
|
557
576
|
}, _callee8, this);
|
|
558
577
|
}));
|
|
559
578
|
|
|
560
|
-
function getItems(
|
|
579
|
+
function getItems(_x19, _x20) {
|
|
561
580
|
return _getItems.apply(this, arguments);
|
|
562
581
|
}
|
|
563
582
|
|
|
@@ -592,7 +611,7 @@ var MediaStore = /*#__PURE__*/function () {
|
|
|
592
611
|
}, _callee9, this);
|
|
593
612
|
}));
|
|
594
613
|
|
|
595
|
-
function getImageMetadata(
|
|
614
|
+
function getImageMetadata(_x21, _x22) {
|
|
596
615
|
return _getImageMetadata.apply(this, arguments);
|
|
597
616
|
}
|
|
598
617
|
|
|
@@ -629,7 +648,7 @@ var MediaStore = /*#__PURE__*/function () {
|
|
|
629
648
|
}, _callee10, this);
|
|
630
649
|
}));
|
|
631
650
|
|
|
632
|
-
function appendChunksToUpload(_x24, _x25
|
|
651
|
+
function appendChunksToUpload(_x23, _x24, _x25) {
|
|
633
652
|
return _appendChunksToUpload.apply(this, arguments);
|
|
634
653
|
}
|
|
635
654
|
|
|
@@ -714,7 +733,7 @@ var MediaStore = /*#__PURE__*/function () {
|
|
|
714
733
|
}, _callee11, this);
|
|
715
734
|
}));
|
|
716
735
|
|
|
717
|
-
function request(
|
|
736
|
+
function request(_x26) {
|
|
718
737
|
return _request2.apply(this, arguments);
|
|
719
738
|
}
|
|
720
739
|
|
package/dist/cjs/constants.js
CHANGED
|
@@ -3,11 +3,20 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.RECENTS_COLLECTION = exports.MAX_RESOLUTION = exports.FILE_CACHE_MAX_AGE = void 0;
|
|
6
|
+
exports.RECENTS_COLLECTION = exports.PROCESSING_BATCH_SIZE = exports.MAX_UPLOAD_FILE_SIZE = exports.MAX_RESOLUTION = exports.FILE_CACHE_MAX_AGE = exports.CHUNK_SIZE = void 0;
|
|
7
|
+
|
|
8
|
+
var _media = require("./models/media");
|
|
9
|
+
|
|
7
10
|
var RECENTS_COLLECTION = 'recents';
|
|
8
11
|
exports.RECENTS_COLLECTION = RECENTS_COLLECTION;
|
|
9
12
|
var FILE_CACHE_MAX_AGE = 60 * 60 * 24 * 30; // Retain for 30 days
|
|
10
13
|
|
|
11
14
|
exports.FILE_CACHE_MAX_AGE = FILE_CACHE_MAX_AGE;
|
|
12
15
|
var MAX_RESOLUTION = 4096;
|
|
13
|
-
exports.MAX_RESOLUTION = MAX_RESOLUTION;
|
|
16
|
+
exports.MAX_RESOLUTION = MAX_RESOLUTION;
|
|
17
|
+
var CHUNK_SIZE = 4 * _media.DATA_UNIT.MB;
|
|
18
|
+
exports.CHUNK_SIZE = CHUNK_SIZE;
|
|
19
|
+
var PROCESSING_BATCH_SIZE = 1000;
|
|
20
|
+
exports.PROCESSING_BATCH_SIZE = PROCESSING_BATCH_SIZE;
|
|
21
|
+
var MAX_UPLOAD_FILE_SIZE = 2 * _media.DATA_UNIT.TB;
|
|
22
|
+
exports.MAX_UPLOAD_FILE_SIZE = MAX_UPLOAD_FILE_SIZE;
|
package/dist/cjs/models/media.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.isPreviewableType = exports.isMediaCollectionItemFullDetails = void 0;
|
|
6
|
+
exports.isPreviewableType = exports.isMediaCollectionItemFullDetails = exports.DATA_UNIT = void 0;
|
|
7
7
|
|
|
8
8
|
var _mediaCommon = require("@atlaskit/media-common");
|
|
9
9
|
|
|
@@ -24,4 +24,12 @@ var isMediaCollectionItemFullDetails = function isMediaCollectionItemFullDetails
|
|
|
24
24
|
return !!mediaCollectionItem['mediaType'] && !!mediaCollectionItem['mimeType'] && !!mediaCollectionItem['processingStatus'];
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
exports.isMediaCollectionItemFullDetails = isMediaCollectionItemFullDetails;
|
|
27
|
+
exports.isMediaCollectionItemFullDetails = isMediaCollectionItemFullDetails;
|
|
28
|
+
var DATA_UNIT;
|
|
29
|
+
exports.DATA_UNIT = DATA_UNIT;
|
|
30
|
+
|
|
31
|
+
(function (DATA_UNIT) {
|
|
32
|
+
DATA_UNIT[DATA_UNIT["MB"] = 1048576] = "MB";
|
|
33
|
+
DATA_UNIT[DATA_UNIT["GB"] = 1073741824] = "GB";
|
|
34
|
+
DATA_UNIT[DATA_UNIT["TB"] = 1099511627776] = "TB";
|
|
35
|
+
})(DATA_UNIT || (exports.DATA_UNIT = DATA_UNIT = {}));
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.fileSizeError = exports.calculateChunkSize = void 0;
|
|
7
|
+
|
|
8
|
+
var _media = require("../models/media");
|
|
9
|
+
|
|
10
|
+
var _constants = require("../constants");
|
|
11
|
+
|
|
12
|
+
var fileSizeError = 'fileSizeExceedsLimit';
|
|
13
|
+
/**
|
|
14
|
+
* This is a helper to dynamically calculate the chunk size for a given file size.
|
|
15
|
+
*
|
|
16
|
+
* @param fileSize The size of a file to calculate the chunk size for.
|
|
17
|
+
* @returns A number of bytes per chunk or Throws an Error if the file size exceeds 2TB
|
|
18
|
+
*
|
|
19
|
+
* @see {@link https://product-fabric.atlassian.net/wiki/spaces/FIL/pages/3221881143/Rule+of+thumb+for+chunk+sizes#Given-the-following-conditions}
|
|
20
|
+
*
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
exports.fileSizeError = fileSizeError;
|
|
24
|
+
|
|
25
|
+
var calculateChunkSize = function calculateChunkSize(fileSize) {
|
|
26
|
+
if (fileSize > _constants.MAX_UPLOAD_FILE_SIZE) {
|
|
27
|
+
throw new Error(fileSizeError);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (fileSize <= 5 * _media.DATA_UNIT.GB) {
|
|
31
|
+
return 5 * _media.DATA_UNIT.MB;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (fileSize > 5 * _media.DATA_UNIT.GB && fileSize <= 50 * _media.DATA_UNIT.GB) {
|
|
35
|
+
return 50 * _media.DATA_UNIT.MB;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (fileSize > 50 * _media.DATA_UNIT.GB && fileSize <= 0.95 * _media.DATA_UNIT.TB) {
|
|
39
|
+
return 100 * _media.DATA_UNIT.MB;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return 210 * _media.DATA_UNIT.MB;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
exports.calculateChunkSize = calculateChunkSize;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.UploaderError = void 0;
|
|
9
|
+
exports.isUploaderError = isUploaderError;
|
|
10
|
+
|
|
11
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
12
|
+
|
|
13
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
14
|
+
|
|
15
|
+
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
|
|
16
|
+
|
|
17
|
+
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
|
|
18
|
+
|
|
19
|
+
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
|
|
20
|
+
|
|
21
|
+
var _errors = require("../models/errors");
|
|
22
|
+
|
|
23
|
+
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
|
|
24
|
+
|
|
25
|
+
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
|
26
|
+
|
|
27
|
+
var UploaderError = /*#__PURE__*/function (_BaseMediaClientError) {
|
|
28
|
+
(0, _inherits2.default)(UploaderError, _BaseMediaClientError);
|
|
29
|
+
|
|
30
|
+
var _super = _createSuper(UploaderError);
|
|
31
|
+
|
|
32
|
+
function UploaderError(reason, id, metadata) {
|
|
33
|
+
var _this;
|
|
34
|
+
|
|
35
|
+
(0, _classCallCheck2.default)(this, UploaderError);
|
|
36
|
+
_this = _super.call(this, reason);
|
|
37
|
+
_this.reason = reason;
|
|
38
|
+
_this.id = id;
|
|
39
|
+
_this.metadata = metadata;
|
|
40
|
+
return _this;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
(0, _createClass2.default)(UploaderError, [{
|
|
44
|
+
key: "attributes",
|
|
45
|
+
get: function get() {
|
|
46
|
+
var reason = this.reason,
|
|
47
|
+
id = this.id,
|
|
48
|
+
_this$metadata = this.metadata;
|
|
49
|
+
_this$metadata = _this$metadata === void 0 ? {} : _this$metadata;
|
|
50
|
+
var collectionName = _this$metadata.collectionName,
|
|
51
|
+
occurrenceKey = _this$metadata.occurrenceKey;
|
|
52
|
+
return {
|
|
53
|
+
reason: reason,
|
|
54
|
+
id: id,
|
|
55
|
+
collectionName: collectionName,
|
|
56
|
+
occurrenceKey: occurrenceKey
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}]);
|
|
60
|
+
return UploaderError;
|
|
61
|
+
}(_errors.BaseMediaClientError);
|
|
62
|
+
|
|
63
|
+
exports.UploaderError = UploaderError;
|
|
64
|
+
|
|
65
|
+
function isUploaderError(err) {
|
|
66
|
+
return err instanceof UploaderError;
|
|
67
|
+
}
|
|
@@ -17,7 +17,15 @@ var _from = require("rxjs/observable/from");
|
|
|
17
17
|
|
|
18
18
|
var _concatMap = require("rxjs/operators/concatMap");
|
|
19
19
|
|
|
20
|
-
var _hasherCreator = require("
|
|
20
|
+
var _hasherCreator = require("../utils/hashing/hasherCreator");
|
|
21
|
+
|
|
22
|
+
var _error = require("./error");
|
|
23
|
+
|
|
24
|
+
var _constants = require("../constants");
|
|
25
|
+
|
|
26
|
+
var _calculateChunkSize = require("./calculateChunkSize");
|
|
27
|
+
|
|
28
|
+
var _mediaCommon = require("@atlaskit/media-common");
|
|
21
29
|
|
|
22
30
|
var hashingFunction = /*#__PURE__*/function () {
|
|
23
31
|
var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(blob) {
|
|
@@ -46,7 +54,7 @@ var hashingFunction = /*#__PURE__*/function () {
|
|
|
46
54
|
};
|
|
47
55
|
}();
|
|
48
56
|
|
|
49
|
-
var createProbingFunction = function createProbingFunction(store,
|
|
57
|
+
var createProbingFunction = function createProbingFunction(store, collectionName) {
|
|
50
58
|
return /*#__PURE__*/function () {
|
|
51
59
|
var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(chunks) {
|
|
52
60
|
var response, results;
|
|
@@ -55,7 +63,9 @@ var createProbingFunction = function createProbingFunction(store, collection) {
|
|
|
55
63
|
switch (_context2.prev = _context2.next) {
|
|
56
64
|
case 0:
|
|
57
65
|
_context2.next = 2;
|
|
58
|
-
return store.probeChunks(hashedChunks(chunks),
|
|
66
|
+
return store.probeChunks(hashedChunks(chunks), {
|
|
67
|
+
collectionName: collectionName
|
|
68
|
+
});
|
|
59
69
|
|
|
60
70
|
case 2:
|
|
61
71
|
response = _context2.sent;
|
|
@@ -78,9 +88,11 @@ var createProbingFunction = function createProbingFunction(store, collection) {
|
|
|
78
88
|
}();
|
|
79
89
|
};
|
|
80
90
|
|
|
81
|
-
var createUploadingFunction = function createUploadingFunction(store,
|
|
91
|
+
var createUploadingFunction = function createUploadingFunction(store, collectionName) {
|
|
82
92
|
return function (chunk) {
|
|
83
|
-
return store.uploadChunk(chunk.hash, chunk.blob,
|
|
93
|
+
return store.uploadChunk(chunk.hash, chunk.blob, {
|
|
94
|
+
collectionName: collectionName
|
|
95
|
+
});
|
|
84
96
|
};
|
|
85
97
|
};
|
|
86
98
|
|
|
@@ -156,11 +168,32 @@ var createFileFromUpload = /*#__PURE__*/function () {
|
|
|
156
168
|
}();
|
|
157
169
|
|
|
158
170
|
var uploadFile = function uploadFile(file, store, uploadableFileUpfrontIds, callbacks) {
|
|
159
|
-
var chunkSize = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 4 * 1024 * 1024;
|
|
160
|
-
var processingBatchSize = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 1000;
|
|
161
171
|
var content = file.content,
|
|
162
172
|
collection = file.collection;
|
|
163
|
-
var deferredUploadId = uploadableFileUpfrontIds.deferredUploadId
|
|
173
|
+
var deferredUploadId = uploadableFileUpfrontIds.deferredUploadId,
|
|
174
|
+
id = uploadableFileUpfrontIds.id,
|
|
175
|
+
occurrenceKey = uploadableFileUpfrontIds.occurrenceKey;
|
|
176
|
+
var chunkSize = _constants.CHUNK_SIZE;
|
|
177
|
+
|
|
178
|
+
try {
|
|
179
|
+
if (content instanceof Blob && (0, _mediaCommon.getMediaFeatureFlag)('mediaUploadApiV2', store.featureFlags)) {
|
|
180
|
+
chunkSize = (0, _calculateChunkSize.calculateChunkSize)(content.size);
|
|
181
|
+
}
|
|
182
|
+
} catch (err) {
|
|
183
|
+
if (err instanceof Error && err.message === _calculateChunkSize.fileSizeError) {
|
|
184
|
+
callbacks === null || callbacks === void 0 ? void 0 : callbacks.onUploadFinish(new _error.UploaderError(err.message, id, {
|
|
185
|
+
collectionName: collection,
|
|
186
|
+
occurrenceKey: occurrenceKey
|
|
187
|
+
}));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return {
|
|
191
|
+
cancel: function cancel() {
|
|
192
|
+
callbacks === null || callbacks === void 0 ? void 0 : callbacks.onUploadFinish('canceled');
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
164
197
|
var chunkinatorObservable = (0, _chunkinator.chunkinator)(content, {
|
|
165
198
|
hashingFunction: hashingFunction,
|
|
166
199
|
hashingConcurrency: 5,
|
|
@@ -169,7 +202,7 @@ var uploadFile = function uploadFile(file, store, uploadableFileUpfrontIds, call
|
|
|
169
202
|
uploadingConcurrency: 3,
|
|
170
203
|
uploadingFunction: createUploadingFunction(store, collection),
|
|
171
204
|
probingFunction: createProbingFunction(store, collection),
|
|
172
|
-
processingBatchSize:
|
|
205
|
+
processingBatchSize: _constants.PROCESSING_BATCH_SIZE,
|
|
173
206
|
processingFunction: createProcessingFunction(store, deferredUploadId, collection)
|
|
174
207
|
}, {
|
|
175
208
|
onProgress: function onProgress(progress) {
|
package/dist/cjs/version.json
CHANGED
|
@@ -122,12 +122,20 @@ export class MediaStore {
|
|
|
122
122
|
return this.request(`/upload`, options).then(createMapResponseToJson(metadata));
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
async uploadChunk(etag, blob,
|
|
125
|
+
async uploadChunk(etag, blob, {
|
|
126
|
+
collectionName,
|
|
127
|
+
uploadId,
|
|
128
|
+
partNumber
|
|
129
|
+
} = {}) {
|
|
126
130
|
const metadata = {
|
|
127
131
|
method: 'PUT',
|
|
128
132
|
endpoint: '/chunk/{etag}'
|
|
129
133
|
};
|
|
130
134
|
const options = { ...metadata,
|
|
135
|
+
params: {
|
|
136
|
+
uploadId,
|
|
137
|
+
partNumber
|
|
138
|
+
},
|
|
131
139
|
authContext: {
|
|
132
140
|
collectionName
|
|
133
141
|
},
|
|
@@ -136,12 +144,18 @@ export class MediaStore {
|
|
|
136
144
|
await this.request(`/chunk/${etag}`, options);
|
|
137
145
|
}
|
|
138
146
|
|
|
139
|
-
probeChunks(chunks,
|
|
147
|
+
probeChunks(chunks, {
|
|
148
|
+
collectionName,
|
|
149
|
+
uploadId
|
|
150
|
+
} = {}) {
|
|
140
151
|
const metadata = {
|
|
141
152
|
method: 'POST',
|
|
142
153
|
endpoint: '/chunk/probe'
|
|
143
154
|
};
|
|
144
155
|
const options = { ...metadata,
|
|
156
|
+
params: {
|
|
157
|
+
uploadId
|
|
158
|
+
},
|
|
145
159
|
authContext: {
|
|
146
160
|
collectionName
|
|
147
161
|
},
|
package/dist/es2019/constants.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import { DATA_UNIT } from './models/media';
|
|
1
2
|
export const RECENTS_COLLECTION = 'recents';
|
|
2
3
|
export const FILE_CACHE_MAX_AGE = 60 * 60 * 24 * 30; // Retain for 30 days
|
|
3
4
|
|
|
4
|
-
export const MAX_RESOLUTION = 4096;
|
|
5
|
+
export const MAX_RESOLUTION = 4096;
|
|
6
|
+
export const CHUNK_SIZE = 4 * DATA_UNIT.MB;
|
|
7
|
+
export const PROCESSING_BATCH_SIZE = 1000;
|
|
8
|
+
export const MAX_UPLOAD_FILE_SIZE = 2 * DATA_UNIT.TB;
|
|
@@ -9,4 +9,11 @@ export const isPreviewableType = (type, featureFlags) => {
|
|
|
9
9
|
|
|
10
10
|
return defaultPreviewableTypes.indexOf(type) > -1;
|
|
11
11
|
};
|
|
12
|
-
export const isMediaCollectionItemFullDetails = mediaCollectionItem => !!mediaCollectionItem['mediaType'] && !!mediaCollectionItem['mimeType'] && !!mediaCollectionItem['processingStatus'];
|
|
12
|
+
export const isMediaCollectionItemFullDetails = mediaCollectionItem => !!mediaCollectionItem['mediaType'] && !!mediaCollectionItem['mimeType'] && !!mediaCollectionItem['processingStatus'];
|
|
13
|
+
export let DATA_UNIT;
|
|
14
|
+
|
|
15
|
+
(function (DATA_UNIT) {
|
|
16
|
+
DATA_UNIT[DATA_UNIT["MB"] = 1048576] = "MB";
|
|
17
|
+
DATA_UNIT[DATA_UNIT["GB"] = 1073741824] = "GB";
|
|
18
|
+
DATA_UNIT[DATA_UNIT["TB"] = 1099511627776] = "TB";
|
|
19
|
+
})(DATA_UNIT || (DATA_UNIT = {}));
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { DATA_UNIT } from '../models/media';
|
|
2
|
+
import { MAX_UPLOAD_FILE_SIZE } from '../constants';
|
|
3
|
+
export const fileSizeError = 'fileSizeExceedsLimit';
|
|
4
|
+
/**
|
|
5
|
+
* This is a helper to dynamically calculate the chunk size for a given file size.
|
|
6
|
+
*
|
|
7
|
+
* @param fileSize The size of a file to calculate the chunk size for.
|
|
8
|
+
* @returns A number of bytes per chunk or Throws an Error if the file size exceeds 2TB
|
|
9
|
+
*
|
|
10
|
+
* @see {@link https://product-fabric.atlassian.net/wiki/spaces/FIL/pages/3221881143/Rule+of+thumb+for+chunk+sizes#Given-the-following-conditions}
|
|
11
|
+
*
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export const calculateChunkSize = fileSize => {
|
|
15
|
+
if (fileSize > MAX_UPLOAD_FILE_SIZE) {
|
|
16
|
+
throw new Error(fileSizeError);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (fileSize <= 5 * DATA_UNIT.GB) {
|
|
20
|
+
return 5 * DATA_UNIT.MB;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (fileSize > 5 * DATA_UNIT.GB && fileSize <= 50 * DATA_UNIT.GB) {
|
|
24
|
+
return 50 * DATA_UNIT.MB;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (fileSize > 50 * DATA_UNIT.GB && fileSize <= 0.95 * DATA_UNIT.TB) {
|
|
28
|
+
return 100 * DATA_UNIT.MB;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return 210 * DATA_UNIT.MB;
|
|
32
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { BaseMediaClientError } from '../models/errors';
|
|
2
|
+
export class UploaderError extends BaseMediaClientError {
|
|
3
|
+
constructor(reason, id, metadata) {
|
|
4
|
+
super(reason);
|
|
5
|
+
this.reason = reason;
|
|
6
|
+
this.id = id;
|
|
7
|
+
this.metadata = metadata;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
get attributes() {
|
|
11
|
+
const {
|
|
12
|
+
reason,
|
|
13
|
+
id,
|
|
14
|
+
metadata: {
|
|
15
|
+
collectionName,
|
|
16
|
+
occurrenceKey
|
|
17
|
+
} = {}
|
|
18
|
+
} = this;
|
|
19
|
+
return {
|
|
20
|
+
reason,
|
|
21
|
+
id,
|
|
22
|
+
collectionName,
|
|
23
|
+
occurrenceKey
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
export function isUploaderError(err) {
|
|
29
|
+
return err instanceof UploaderError;
|
|
30
|
+
}
|
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
import { chunkinator } from '@atlaskit/chunkinator';
|
|
2
2
|
import { from } from 'rxjs/observable/from';
|
|
3
3
|
import { concatMap } from 'rxjs/operators/concatMap';
|
|
4
|
-
import { createHasher } from '
|
|
4
|
+
import { createHasher } from '../utils/hashing/hasherCreator';
|
|
5
|
+
import { UploaderError } from './error';
|
|
6
|
+
import { CHUNK_SIZE, PROCESSING_BATCH_SIZE } from '../constants';
|
|
7
|
+
import { calculateChunkSize, fileSizeError } from './calculateChunkSize';
|
|
8
|
+
import { getMediaFeatureFlag } from '@atlaskit/media-common'; // TODO: Allow to pass multiple files
|
|
5
9
|
|
|
6
10
|
const hashingFunction = async blob => {
|
|
7
11
|
const hasher = await createHasher();
|
|
8
12
|
return hasher.hash(blob);
|
|
9
13
|
};
|
|
10
14
|
|
|
11
|
-
const createProbingFunction = (store,
|
|
12
|
-
const response = await store.probeChunks(hashedChunks(chunks),
|
|
15
|
+
const createProbingFunction = (store, collectionName) => async chunks => {
|
|
16
|
+
const response = await store.probeChunks(hashedChunks(chunks), {
|
|
17
|
+
collectionName
|
|
18
|
+
});
|
|
13
19
|
const results = response.data.results;
|
|
14
20
|
return Object.values(results).map(result => result.exists);
|
|
15
21
|
};
|
|
16
22
|
|
|
17
|
-
const createUploadingFunction = (store,
|
|
18
|
-
return chunk => store.uploadChunk(chunk.hash, chunk.blob,
|
|
23
|
+
const createUploadingFunction = (store, collectionName) => {
|
|
24
|
+
return chunk => store.uploadChunk(chunk.hash, chunk.blob, {
|
|
25
|
+
collectionName
|
|
26
|
+
});
|
|
19
27
|
};
|
|
20
28
|
|
|
21
29
|
const createProcessingFunction = (store, deferredUploadId, collection) => {
|
|
@@ -50,14 +58,37 @@ const createFileFromUpload = async (file, store, uploadableFileUpfrontIds, uploa
|
|
|
50
58
|
});
|
|
51
59
|
};
|
|
52
60
|
|
|
53
|
-
export const uploadFile = (file, store, uploadableFileUpfrontIds, callbacks
|
|
61
|
+
export const uploadFile = (file, store, uploadableFileUpfrontIds, callbacks) => {
|
|
54
62
|
const {
|
|
55
63
|
content,
|
|
56
64
|
collection
|
|
57
65
|
} = file;
|
|
58
66
|
const {
|
|
59
|
-
deferredUploadId
|
|
67
|
+
deferredUploadId,
|
|
68
|
+
id,
|
|
69
|
+
occurrenceKey
|
|
60
70
|
} = uploadableFileUpfrontIds;
|
|
71
|
+
let chunkSize = CHUNK_SIZE;
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
if (content instanceof Blob && getMediaFeatureFlag('mediaUploadApiV2', store.featureFlags)) {
|
|
75
|
+
chunkSize = calculateChunkSize(content.size);
|
|
76
|
+
}
|
|
77
|
+
} catch (err) {
|
|
78
|
+
if (err instanceof Error && err.message === fileSizeError) {
|
|
79
|
+
callbacks === null || callbacks === void 0 ? void 0 : callbacks.onUploadFinish(new UploaderError(err.message, id, {
|
|
80
|
+
collectionName: collection,
|
|
81
|
+
occurrenceKey: occurrenceKey
|
|
82
|
+
}));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
cancel: () => {
|
|
87
|
+
callbacks === null || callbacks === void 0 ? void 0 : callbacks.onUploadFinish('canceled');
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
61
92
|
const chunkinatorObservable = chunkinator(content, {
|
|
62
93
|
hashingFunction,
|
|
63
94
|
hashingConcurrency: 5,
|
|
@@ -66,7 +97,7 @@ export const uploadFile = (file, store, uploadableFileUpfrontIds, callbacks, chu
|
|
|
66
97
|
uploadingConcurrency: 3,
|
|
67
98
|
uploadingFunction: createUploadingFunction(store, collection),
|
|
68
99
|
probingFunction: createProbingFunction(store, collection),
|
|
69
|
-
processingBatchSize,
|
|
100
|
+
processingBatchSize: PROCESSING_BATCH_SIZE,
|
|
70
101
|
processingFunction: createProcessingFunction(store, deferredUploadId, collection)
|
|
71
102
|
}, {
|
|
72
103
|
onProgress(progress) {
|
package/dist/es2019/version.json
CHANGED
|
@@ -195,26 +195,38 @@ export var MediaStore = /*#__PURE__*/function () {
|
|
|
195
195
|
}, {
|
|
196
196
|
key: "uploadChunk",
|
|
197
197
|
value: function () {
|
|
198
|
-
var _uploadChunk = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(etag, blob
|
|
199
|
-
var
|
|
198
|
+
var _uploadChunk = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(etag, blob) {
|
|
199
|
+
var _ref,
|
|
200
|
+
collectionName,
|
|
201
|
+
uploadId,
|
|
202
|
+
partNumber,
|
|
203
|
+
metadata,
|
|
204
|
+
options,
|
|
205
|
+
_args3 = arguments;
|
|
206
|
+
|
|
200
207
|
return _regeneratorRuntime.wrap(function _callee3$(_context3) {
|
|
201
208
|
while (1) {
|
|
202
209
|
switch (_context3.prev = _context3.next) {
|
|
203
210
|
case 0:
|
|
211
|
+
_ref = _args3.length > 2 && _args3[2] !== undefined ? _args3[2] : {}, collectionName = _ref.collectionName, uploadId = _ref.uploadId, partNumber = _ref.partNumber;
|
|
204
212
|
metadata = {
|
|
205
213
|
method: 'PUT',
|
|
206
214
|
endpoint: '/chunk/{etag}'
|
|
207
215
|
};
|
|
208
216
|
options = _objectSpread(_objectSpread({}, metadata), {}, {
|
|
217
|
+
params: {
|
|
218
|
+
uploadId: uploadId,
|
|
219
|
+
partNumber: partNumber
|
|
220
|
+
},
|
|
209
221
|
authContext: {
|
|
210
222
|
collectionName: collectionName
|
|
211
223
|
},
|
|
212
224
|
body: blob
|
|
213
225
|
});
|
|
214
|
-
_context3.next =
|
|
226
|
+
_context3.next = 5;
|
|
215
227
|
return this.request("/chunk/".concat(etag), options);
|
|
216
228
|
|
|
217
|
-
case
|
|
229
|
+
case 5:
|
|
218
230
|
case "end":
|
|
219
231
|
return _context3.stop();
|
|
220
232
|
}
|
|
@@ -222,7 +234,7 @@ export var MediaStore = /*#__PURE__*/function () {
|
|
|
222
234
|
}, _callee3, this);
|
|
223
235
|
}));
|
|
224
236
|
|
|
225
|
-
function uploadChunk(_x6, _x7
|
|
237
|
+
function uploadChunk(_x6, _x7) {
|
|
226
238
|
return _uploadChunk.apply(this, arguments);
|
|
227
239
|
}
|
|
228
240
|
|
|
@@ -230,13 +242,20 @@ export var MediaStore = /*#__PURE__*/function () {
|
|
|
230
242
|
}()
|
|
231
243
|
}, {
|
|
232
244
|
key: "probeChunks",
|
|
233
|
-
value: function probeChunks(chunks
|
|
245
|
+
value: function probeChunks(chunks) {
|
|
246
|
+
var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
|
|
247
|
+
collectionName = _ref2.collectionName,
|
|
248
|
+
uploadId = _ref2.uploadId;
|
|
249
|
+
|
|
234
250
|
var metadata = {
|
|
235
251
|
method: 'POST',
|
|
236
252
|
endpoint: '/chunk/probe'
|
|
237
253
|
};
|
|
238
254
|
|
|
239
255
|
var options = _objectSpread(_objectSpread({}, metadata), {}, {
|
|
256
|
+
params: {
|
|
257
|
+
uploadId: uploadId
|
|
258
|
+
},
|
|
240
259
|
authContext: {
|
|
241
260
|
collectionName: collectionName
|
|
242
261
|
},
|
|
@@ -309,13 +328,13 @@ export var MediaStore = /*#__PURE__*/function () {
|
|
|
309
328
|
key: "getFileImageURL",
|
|
310
329
|
value: function () {
|
|
311
330
|
var _getFileImageURL = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4(id, params) {
|
|
312
|
-
var
|
|
331
|
+
var _ref3, collectionName, auth;
|
|
313
332
|
|
|
314
333
|
return _regeneratorRuntime.wrap(function _callee4$(_context4) {
|
|
315
334
|
while (1) {
|
|
316
335
|
switch (_context4.prev = _context4.next) {
|
|
317
336
|
case 0:
|
|
318
|
-
|
|
337
|
+
_ref3 = params || {}, collectionName = _ref3.collection;
|
|
319
338
|
_context4.next = 3;
|
|
320
339
|
return this.resolveAuth({
|
|
321
340
|
collectionName: collectionName
|
|
@@ -333,7 +352,7 @@ export var MediaStore = /*#__PURE__*/function () {
|
|
|
333
352
|
}, _callee4, this);
|
|
334
353
|
}));
|
|
335
354
|
|
|
336
|
-
function getFileImageURL(
|
|
355
|
+
function getFileImageURL(_x8, _x9) {
|
|
337
356
|
return _getFileImageURL.apply(this, arguments);
|
|
338
357
|
}
|
|
339
358
|
|
|
@@ -388,7 +407,7 @@ export var MediaStore = /*#__PURE__*/function () {
|
|
|
388
407
|
}, _callee5, this);
|
|
389
408
|
}));
|
|
390
409
|
|
|
391
|
-
function getFileBinaryURL(
|
|
410
|
+
function getFileBinaryURL(_x10, _x11) {
|
|
392
411
|
return _getFileBinaryURL.apply(this, arguments);
|
|
393
412
|
}
|
|
394
413
|
|
|
@@ -437,7 +456,7 @@ export var MediaStore = /*#__PURE__*/function () {
|
|
|
437
456
|
}, _callee6, this);
|
|
438
457
|
}));
|
|
439
458
|
|
|
440
|
-
function getArtifactURL(_x13, _x14
|
|
459
|
+
function getArtifactURL(_x12, _x13, _x14) {
|
|
441
460
|
return _getArtifactURL.apply(this, arguments);
|
|
442
461
|
}
|
|
443
462
|
|
|
@@ -482,7 +501,7 @@ export var MediaStore = /*#__PURE__*/function () {
|
|
|
482
501
|
}, _callee7, this);
|
|
483
502
|
}));
|
|
484
503
|
|
|
485
|
-
function getImage(_x16, _x17, _x18
|
|
504
|
+
function getImage(_x15, _x16, _x17, _x18) {
|
|
486
505
|
return _getImage.apply(this, arguments);
|
|
487
506
|
}
|
|
488
507
|
|
|
@@ -527,7 +546,7 @@ export var MediaStore = /*#__PURE__*/function () {
|
|
|
527
546
|
}, _callee8, this);
|
|
528
547
|
}));
|
|
529
548
|
|
|
530
|
-
function getItems(
|
|
549
|
+
function getItems(_x19, _x20) {
|
|
531
550
|
return _getItems.apply(this, arguments);
|
|
532
551
|
}
|
|
533
552
|
|
|
@@ -562,7 +581,7 @@ export var MediaStore = /*#__PURE__*/function () {
|
|
|
562
581
|
}, _callee9, this);
|
|
563
582
|
}));
|
|
564
583
|
|
|
565
|
-
function getImageMetadata(
|
|
584
|
+
function getImageMetadata(_x21, _x22) {
|
|
566
585
|
return _getImageMetadata.apply(this, arguments);
|
|
567
586
|
}
|
|
568
587
|
|
|
@@ -599,7 +618,7 @@ export var MediaStore = /*#__PURE__*/function () {
|
|
|
599
618
|
}, _callee10, this);
|
|
600
619
|
}));
|
|
601
620
|
|
|
602
|
-
function appendChunksToUpload(_x24, _x25
|
|
621
|
+
function appendChunksToUpload(_x23, _x24, _x25) {
|
|
603
622
|
return _appendChunksToUpload.apply(this, arguments);
|
|
604
623
|
}
|
|
605
624
|
|
|
@@ -684,7 +703,7 @@ export var MediaStore = /*#__PURE__*/function () {
|
|
|
684
703
|
}, _callee11, this);
|
|
685
704
|
}));
|
|
686
705
|
|
|
687
|
-
function request(
|
|
706
|
+
function request(_x26) {
|
|
688
707
|
return _request2.apply(this, arguments);
|
|
689
708
|
}
|
|
690
709
|
|
package/dist/esm/constants.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import { DATA_UNIT } from './models/media';
|
|
1
2
|
export var RECENTS_COLLECTION = 'recents';
|
|
2
3
|
export var FILE_CACHE_MAX_AGE = 60 * 60 * 24 * 30; // Retain for 30 days
|
|
3
4
|
|
|
4
|
-
export var MAX_RESOLUTION = 4096;
|
|
5
|
+
export var MAX_RESOLUTION = 4096;
|
|
6
|
+
export var CHUNK_SIZE = 4 * DATA_UNIT.MB;
|
|
7
|
+
export var PROCESSING_BATCH_SIZE = 1000;
|
|
8
|
+
export var MAX_UPLOAD_FILE_SIZE = 2 * DATA_UNIT.TB;
|
package/dist/esm/models/media.js
CHANGED
|
@@ -11,4 +11,11 @@ export var isPreviewableType = function isPreviewableType(type, featureFlags) {
|
|
|
11
11
|
};
|
|
12
12
|
export var isMediaCollectionItemFullDetails = function isMediaCollectionItemFullDetails(mediaCollectionItem) {
|
|
13
13
|
return !!mediaCollectionItem['mediaType'] && !!mediaCollectionItem['mimeType'] && !!mediaCollectionItem['processingStatus'];
|
|
14
|
-
};
|
|
14
|
+
};
|
|
15
|
+
export var DATA_UNIT;
|
|
16
|
+
|
|
17
|
+
(function (DATA_UNIT) {
|
|
18
|
+
DATA_UNIT[DATA_UNIT["MB"] = 1048576] = "MB";
|
|
19
|
+
DATA_UNIT[DATA_UNIT["GB"] = 1073741824] = "GB";
|
|
20
|
+
DATA_UNIT[DATA_UNIT["TB"] = 1099511627776] = "TB";
|
|
21
|
+
})(DATA_UNIT || (DATA_UNIT = {}));
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { DATA_UNIT } from '../models/media';
|
|
2
|
+
import { MAX_UPLOAD_FILE_SIZE } from '../constants';
|
|
3
|
+
export var fileSizeError = 'fileSizeExceedsLimit';
|
|
4
|
+
/**
|
|
5
|
+
* This is a helper to dynamically calculate the chunk size for a given file size.
|
|
6
|
+
*
|
|
7
|
+
* @param fileSize The size of a file to calculate the chunk size for.
|
|
8
|
+
* @returns A number of bytes per chunk or Throws an Error if the file size exceeds 2TB
|
|
9
|
+
*
|
|
10
|
+
* @see {@link https://product-fabric.atlassian.net/wiki/spaces/FIL/pages/3221881143/Rule+of+thumb+for+chunk+sizes#Given-the-following-conditions}
|
|
11
|
+
*
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export var calculateChunkSize = function calculateChunkSize(fileSize) {
|
|
15
|
+
if (fileSize > MAX_UPLOAD_FILE_SIZE) {
|
|
16
|
+
throw new Error(fileSizeError);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (fileSize <= 5 * DATA_UNIT.GB) {
|
|
20
|
+
return 5 * DATA_UNIT.MB;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (fileSize > 5 * DATA_UNIT.GB && fileSize <= 50 * DATA_UNIT.GB) {
|
|
24
|
+
return 50 * DATA_UNIT.MB;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (fileSize > 50 * DATA_UNIT.GB && fileSize <= 0.95 * DATA_UNIT.TB) {
|
|
28
|
+
return 100 * DATA_UNIT.MB;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return 210 * DATA_UNIT.MB;
|
|
32
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
2
|
+
import _createClass from "@babel/runtime/helpers/createClass";
|
|
3
|
+
import _inherits from "@babel/runtime/helpers/inherits";
|
|
4
|
+
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
|
|
5
|
+
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
|
|
6
|
+
|
|
7
|
+
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
|
8
|
+
|
|
9
|
+
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
|
10
|
+
|
|
11
|
+
import { BaseMediaClientError } from '../models/errors';
|
|
12
|
+
export var UploaderError = /*#__PURE__*/function (_BaseMediaClientError) {
|
|
13
|
+
_inherits(UploaderError, _BaseMediaClientError);
|
|
14
|
+
|
|
15
|
+
var _super = _createSuper(UploaderError);
|
|
16
|
+
|
|
17
|
+
function UploaderError(reason, id, metadata) {
|
|
18
|
+
var _this;
|
|
19
|
+
|
|
20
|
+
_classCallCheck(this, UploaderError);
|
|
21
|
+
|
|
22
|
+
_this = _super.call(this, reason);
|
|
23
|
+
_this.reason = reason;
|
|
24
|
+
_this.id = id;
|
|
25
|
+
_this.metadata = metadata;
|
|
26
|
+
return _this;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
_createClass(UploaderError, [{
|
|
30
|
+
key: "attributes",
|
|
31
|
+
get: function get() {
|
|
32
|
+
var reason = this.reason,
|
|
33
|
+
id = this.id,
|
|
34
|
+
_this$metadata = this.metadata;
|
|
35
|
+
_this$metadata = _this$metadata === void 0 ? {} : _this$metadata;
|
|
36
|
+
var collectionName = _this$metadata.collectionName,
|
|
37
|
+
occurrenceKey = _this$metadata.occurrenceKey;
|
|
38
|
+
return {
|
|
39
|
+
reason: reason,
|
|
40
|
+
id: id,
|
|
41
|
+
collectionName: collectionName,
|
|
42
|
+
occurrenceKey: occurrenceKey
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}]);
|
|
46
|
+
|
|
47
|
+
return UploaderError;
|
|
48
|
+
}(BaseMediaClientError);
|
|
49
|
+
export function isUploaderError(err) {
|
|
50
|
+
return err instanceof UploaderError;
|
|
51
|
+
}
|
|
@@ -3,7 +3,11 @@ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
|
3
3
|
import { chunkinator } from '@atlaskit/chunkinator';
|
|
4
4
|
import { from } from 'rxjs/observable/from';
|
|
5
5
|
import { concatMap } from 'rxjs/operators/concatMap';
|
|
6
|
-
import { createHasher } from '
|
|
6
|
+
import { createHasher } from '../utils/hashing/hasherCreator';
|
|
7
|
+
import { UploaderError } from './error';
|
|
8
|
+
import { CHUNK_SIZE, PROCESSING_BATCH_SIZE } from '../constants';
|
|
9
|
+
import { calculateChunkSize, fileSizeError } from './calculateChunkSize';
|
|
10
|
+
import { getMediaFeatureFlag } from '@atlaskit/media-common'; // TODO: Allow to pass multiple files
|
|
7
11
|
|
|
8
12
|
var hashingFunction = /*#__PURE__*/function () {
|
|
9
13
|
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(blob) {
|
|
@@ -32,7 +36,7 @@ var hashingFunction = /*#__PURE__*/function () {
|
|
|
32
36
|
};
|
|
33
37
|
}();
|
|
34
38
|
|
|
35
|
-
var createProbingFunction = function createProbingFunction(store,
|
|
39
|
+
var createProbingFunction = function createProbingFunction(store, collectionName) {
|
|
36
40
|
return /*#__PURE__*/function () {
|
|
37
41
|
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(chunks) {
|
|
38
42
|
var response, results;
|
|
@@ -41,7 +45,9 @@ var createProbingFunction = function createProbingFunction(store, collection) {
|
|
|
41
45
|
switch (_context2.prev = _context2.next) {
|
|
42
46
|
case 0:
|
|
43
47
|
_context2.next = 2;
|
|
44
|
-
return store.probeChunks(hashedChunks(chunks),
|
|
48
|
+
return store.probeChunks(hashedChunks(chunks), {
|
|
49
|
+
collectionName: collectionName
|
|
50
|
+
});
|
|
45
51
|
|
|
46
52
|
case 2:
|
|
47
53
|
response = _context2.sent;
|
|
@@ -64,9 +70,11 @@ var createProbingFunction = function createProbingFunction(store, collection) {
|
|
|
64
70
|
}();
|
|
65
71
|
};
|
|
66
72
|
|
|
67
|
-
var createUploadingFunction = function createUploadingFunction(store,
|
|
73
|
+
var createUploadingFunction = function createUploadingFunction(store, collectionName) {
|
|
68
74
|
return function (chunk) {
|
|
69
|
-
return store.uploadChunk(chunk.hash, chunk.blob,
|
|
75
|
+
return store.uploadChunk(chunk.hash, chunk.blob, {
|
|
76
|
+
collectionName: collectionName
|
|
77
|
+
});
|
|
70
78
|
};
|
|
71
79
|
};
|
|
72
80
|
|
|
@@ -142,11 +150,32 @@ var createFileFromUpload = /*#__PURE__*/function () {
|
|
|
142
150
|
}();
|
|
143
151
|
|
|
144
152
|
export var uploadFile = function uploadFile(file, store, uploadableFileUpfrontIds, callbacks) {
|
|
145
|
-
var chunkSize = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 4 * 1024 * 1024;
|
|
146
|
-
var processingBatchSize = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 1000;
|
|
147
153
|
var content = file.content,
|
|
148
154
|
collection = file.collection;
|
|
149
|
-
var deferredUploadId = uploadableFileUpfrontIds.deferredUploadId
|
|
155
|
+
var deferredUploadId = uploadableFileUpfrontIds.deferredUploadId,
|
|
156
|
+
id = uploadableFileUpfrontIds.id,
|
|
157
|
+
occurrenceKey = uploadableFileUpfrontIds.occurrenceKey;
|
|
158
|
+
var chunkSize = CHUNK_SIZE;
|
|
159
|
+
|
|
160
|
+
try {
|
|
161
|
+
if (content instanceof Blob && getMediaFeatureFlag('mediaUploadApiV2', store.featureFlags)) {
|
|
162
|
+
chunkSize = calculateChunkSize(content.size);
|
|
163
|
+
}
|
|
164
|
+
} catch (err) {
|
|
165
|
+
if (err instanceof Error && err.message === fileSizeError) {
|
|
166
|
+
callbacks === null || callbacks === void 0 ? void 0 : callbacks.onUploadFinish(new UploaderError(err.message, id, {
|
|
167
|
+
collectionName: collection,
|
|
168
|
+
occurrenceKey: occurrenceKey
|
|
169
|
+
}));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
cancel: function cancel() {
|
|
174
|
+
callbacks === null || callbacks === void 0 ? void 0 : callbacks.onUploadFinish('canceled');
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
150
179
|
var chunkinatorObservable = chunkinator(content, {
|
|
151
180
|
hashingFunction: hashingFunction,
|
|
152
181
|
hashingConcurrency: 5,
|
|
@@ -155,7 +184,7 @@ export var uploadFile = function uploadFile(file, store, uploadableFileUpfrontId
|
|
|
155
184
|
uploadingConcurrency: 3,
|
|
156
185
|
uploadingFunction: createUploadingFunction(store, collection),
|
|
157
186
|
probingFunction: createProbingFunction(store, collection),
|
|
158
|
-
processingBatchSize:
|
|
187
|
+
processingBatchSize: PROCESSING_BATCH_SIZE,
|
|
159
188
|
processingFunction: createProcessingFunction(store, deferredUploadId, collection)
|
|
160
189
|
}, {
|
|
161
190
|
onProgress: function onProgress(progress) {
|
package/dist/esm/version.json
CHANGED
|
@@ -12,8 +12,15 @@ export declare class MediaStore {
|
|
|
12
12
|
getCollectionItems(collectionName: string, params?: MediaStoreGetCollectionItemsParams): Promise<MediaStoreResponse<MediaCollectionItems>>;
|
|
13
13
|
removeCollectionFile(id: string, collectionName: string, occurrenceKey?: string): Promise<void>;
|
|
14
14
|
createUpload(createUpTo?: number, collectionName?: string): Promise<MediaStoreResponse<MediaUpload[]>>;
|
|
15
|
-
uploadChunk(etag: string, blob: Blob, collectionName?:
|
|
16
|
-
|
|
15
|
+
uploadChunk(etag: string, blob: Blob, { collectionName, uploadId, partNumber, }?: {
|
|
16
|
+
collectionName?: string;
|
|
17
|
+
uploadId?: string;
|
|
18
|
+
partNumber?: number;
|
|
19
|
+
}): Promise<void>;
|
|
20
|
+
probeChunks(chunks: string[], { collectionName, uploadId, }?: {
|
|
21
|
+
collectionName?: string;
|
|
22
|
+
uploadId?: string;
|
|
23
|
+
}): Promise<MediaStoreResponse<MediaChunksProbe>>;
|
|
17
24
|
createFileFromUpload(body: MediaStoreCreateFileFromUploadBody, params?: MediaStoreCreateFileFromUploadParams): Promise<MediaStoreResponse<MediaFile>>;
|
|
18
25
|
touchFiles(body: MediaStoreTouchFileBody, params?: MediaStoreTouchFileParams): Promise<MediaStoreResponse<TouchedFiles>>;
|
|
19
26
|
getFile(fileId: string, params?: MediaStoreGetFileParams): Promise<MediaStoreResponse<MediaFile>>;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
export declare const RECENTS_COLLECTION = "recents";
|
|
2
2
|
export declare const FILE_CACHE_MAX_AGE: number;
|
|
3
3
|
export declare const MAX_RESOLUTION = 4096;
|
|
4
|
+
export declare const CHUNK_SIZE: number;
|
|
5
|
+
export declare const PROCESSING_BATCH_SIZE = 1000;
|
|
6
|
+
export declare const MAX_UPLOAD_FILE_SIZE: number;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare type MediaClientErrorReason = 'clientOffline' | 'clientAbortedRequest' | 'clientTimeoutRequest' | 'serverInvalidBody' | 'serverBadRequest' | 'serverUnauthorized' | 'serverForbidden' | 'serverNotFound' | 'serverRateLimited' | 'serverInternalError' | 'serverBadGateway' | 'serverUnexpectedError' | 'failedAuthProvider' | 'tokenExpired' | 'missingInitialAuth' | 'emptyAuth' | 'authProviderTimedOut' | 'invalidFileId' | 'emptyItems' | 'zeroVersionFile' | 'pollingMaxAttemptsExceeded';
|
|
1
|
+
export declare type MediaClientErrorReason = 'clientOffline' | 'clientAbortedRequest' | 'clientTimeoutRequest' | 'serverInvalidBody' | 'serverBadRequest' | 'serverUnauthorized' | 'serverForbidden' | 'serverNotFound' | 'serverRateLimited' | 'serverInternalError' | 'serverBadGateway' | 'serverUnexpectedError' | 'failedAuthProvider' | 'tokenExpired' | 'missingInitialAuth' | 'emptyAuth' | 'authProviderTimedOut' | 'invalidFileId' | 'emptyItems' | 'zeroVersionFile' | 'pollingMaxAttemptsExceeded' | 'fileSizeExceedsLimit';
|
|
2
2
|
export interface MediaClientErrorAttributes {
|
|
3
3
|
reason: MediaClientErrorReason;
|
|
4
4
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const fileSizeError = "fileSizeExceedsLimit";
|
|
2
|
+
/**
|
|
3
|
+
* This is a helper to dynamically calculate the chunk size for a given file size.
|
|
4
|
+
*
|
|
5
|
+
* @param fileSize The size of a file to calculate the chunk size for.
|
|
6
|
+
* @returns A number of bytes per chunk or Throws an Error if the file size exceeds 2TB
|
|
7
|
+
*
|
|
8
|
+
* @see {@link https://product-fabric.atlassian.net/wiki/spaces/FIL/pages/3221881143/Rule+of+thumb+for+chunk+sizes#Given-the-following-conditions}
|
|
9
|
+
*
|
|
10
|
+
*/
|
|
11
|
+
export declare const calculateChunkSize: (fileSize: number) => number;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { BaseMediaClientError } from '../models/errors';
|
|
2
|
+
export declare type UploaderErrorReason = 'fileSizeExceedsLimit';
|
|
3
|
+
export declare type UploaderErrorAttributes = {
|
|
4
|
+
readonly reason: UploaderErrorReason;
|
|
5
|
+
readonly id: string;
|
|
6
|
+
readonly metadata?: {
|
|
7
|
+
readonly collectionName?: string;
|
|
8
|
+
readonly occurrenceKey?: string;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
export declare class UploaderError extends BaseMediaClientError<UploaderErrorAttributes> {
|
|
12
|
+
readonly reason: UploaderErrorReason;
|
|
13
|
+
readonly id: string;
|
|
14
|
+
readonly metadata?: {
|
|
15
|
+
readonly collectionName?: string | undefined;
|
|
16
|
+
readonly occurrenceKey?: string | undefined;
|
|
17
|
+
} | undefined;
|
|
18
|
+
constructor(reason: UploaderErrorReason, id: string, metadata?: {
|
|
19
|
+
readonly collectionName?: string | undefined;
|
|
20
|
+
readonly occurrenceKey?: string | undefined;
|
|
21
|
+
} | undefined);
|
|
22
|
+
get attributes(): {
|
|
23
|
+
reason: "fileSizeExceedsLimit";
|
|
24
|
+
id: string;
|
|
25
|
+
collectionName: string | undefined;
|
|
26
|
+
occurrenceKey: string | undefined;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export declare function isUploaderError(err: Error): err is UploaderError;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ChunkinatorFile } from '@atlaskit/chunkinator';
|
|
2
|
-
import { MediaStore } from '
|
|
2
|
+
import { MediaStore } from '../client/media-store';
|
|
3
3
|
export declare type UploadableFile = {
|
|
4
4
|
content: ChunkinatorFile;
|
|
5
5
|
name?: string;
|
|
@@ -18,4 +18,4 @@ export declare type UploadFileCallbacks = {
|
|
|
18
18
|
export interface UploadFileResult {
|
|
19
19
|
cancel: () => void;
|
|
20
20
|
}
|
|
21
|
-
export declare const uploadFile: (file: UploadableFile, store: MediaStore, uploadableFileUpfrontIds: UploadableFileUpfrontIds, callbacks?: UploadFileCallbacks | undefined
|
|
21
|
+
export declare const uploadFile: (file: UploadableFile, store: MediaStore, uploadableFileUpfrontIds: UploadableFileUpfrontIds, callbacks?: UploadFileCallbacks | undefined) => UploadFileResult;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/media-client",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "17.0.0",
|
|
4
4
|
"description": "Media API Web Client Library",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@atlaskit/chunkinator": "^4.0.0",
|
|
31
|
-
"@atlaskit/media-common": "^2.
|
|
31
|
+
"@atlaskit/media-common": "^2.15.0",
|
|
32
32
|
"@babel/runtime": "^7.0.0",
|
|
33
33
|
"dataloader": "^2.0.0",
|
|
34
34
|
"deep-equal": "^1.0.1",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@atlaskit/button": "^16.3.0",
|
|
51
51
|
"@atlaskit/docs": "*",
|
|
52
|
-
"@atlaskit/media-card": "^73.
|
|
52
|
+
"@atlaskit/media-card": "^73.8.0",
|
|
53
53
|
"@atlaskit/media-core": "^33.0.0",
|
|
54
54
|
"@atlaskit/media-test-helpers": "^30.0.0",
|
|
55
55
|
"@atlaskit/ssr": "*",
|