@atlaskit/media-client 14.1.0 → 14.3.1

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 (81) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/cjs/client/file-fetcher/index.js +1 -10
  3. package/dist/cjs/client/media-client.js +50 -1
  4. package/dist/cjs/client/media-store/resolveAuth.js +22 -19
  5. package/dist/cjs/client/mobile-upload.js +98 -0
  6. package/dist/cjs/index.js +8 -0
  7. package/dist/cjs/models/mobile-upload.js +5 -0
  8. package/dist/cjs/utils/imageResizeModeToFileImageMode.js +12 -0
  9. package/dist/cjs/utils/mobileUpload/error.js +67 -0
  10. package/dist/cjs/utils/mobileUpload/helpers.js +110 -0
  11. package/dist/cjs/utils/mobileUpload/index.js +49 -0
  12. package/dist/cjs/utils/mobileUpload/servicesCache.js +12 -0
  13. package/dist/cjs/utils/mobileUpload/stateMachine/index.js +103 -0
  14. package/dist/cjs/utils/mobileUpload/stateMachine/states/error.js +10 -0
  15. package/dist/cjs/utils/mobileUpload/stateMachine/states/processed.js +10 -0
  16. package/dist/cjs/utils/mobileUpload/stateMachine/states/processing.js +77 -0
  17. package/dist/cjs/utils/mobileUpload/stateMachine/states/processingFailed.js +10 -0
  18. package/dist/cjs/utils/mobileUpload/stateMachine/states/uploading.js +70 -0
  19. package/dist/cjs/utils/mobileUpload/stateMachine/types.js +5 -0
  20. package/dist/cjs/utils/polling/index.js +5 -6
  21. package/dist/cjs/version.json +1 -1
  22. package/dist/es2019/client/file-fetcher/index.js +1 -11
  23. package/dist/es2019/client/media-client.js +15 -1
  24. package/dist/es2019/client/media-store/resolveAuth.js +3 -3
  25. package/dist/es2019/client/mobile-upload.js +80 -0
  26. package/dist/es2019/index.js +1 -0
  27. package/dist/es2019/models/mobile-upload.js +1 -0
  28. package/dist/es2019/utils/imageResizeModeToFileImageMode.js +1 -0
  29. package/dist/es2019/utils/mobileUpload/error.js +30 -0
  30. package/dist/es2019/utils/mobileUpload/helpers.js +55 -0
  31. package/dist/es2019/utils/mobileUpload/index.js +4 -0
  32. package/dist/es2019/utils/mobileUpload/servicesCache.js +4 -0
  33. package/dist/es2019/utils/mobileUpload/stateMachine/index.js +52 -0
  34. package/dist/es2019/utils/mobileUpload/stateMachine/states/error.js +3 -0
  35. package/dist/es2019/utils/mobileUpload/stateMachine/states/processed.js +3 -0
  36. package/dist/es2019/utils/mobileUpload/stateMachine/states/processing.js +60 -0
  37. package/dist/es2019/utils/mobileUpload/stateMachine/states/processingFailed.js +3 -0
  38. package/dist/es2019/utils/mobileUpload/stateMachine/states/uploading.js +44 -0
  39. package/dist/es2019/utils/mobileUpload/stateMachine/types.js +1 -0
  40. package/dist/es2019/utils/polling/index.js +5 -5
  41. package/dist/es2019/version.json +1 -1
  42. package/dist/esm/client/file-fetcher/index.js +1 -9
  43. package/dist/esm/client/media-client.js +44 -1
  44. package/dist/esm/client/media-store/resolveAuth.js +20 -17
  45. package/dist/esm/client/mobile-upload.js +83 -0
  46. package/dist/esm/index.js +1 -0
  47. package/dist/esm/models/mobile-upload.js +1 -0
  48. package/dist/esm/utils/imageResizeModeToFileImageMode.js +3 -0
  49. package/dist/esm/utils/mobileUpload/error.js +51 -0
  50. package/dist/esm/utils/mobileUpload/helpers.js +86 -0
  51. package/dist/esm/utils/mobileUpload/index.js +4 -0
  52. package/dist/esm/utils/mobileUpload/servicesCache.js +4 -0
  53. package/dist/esm/utils/mobileUpload/stateMachine/index.js +78 -0
  54. package/dist/esm/utils/mobileUpload/stateMachine/states/error.js +3 -0
  55. package/dist/esm/utils/mobileUpload/stateMachine/states/processed.js +3 -0
  56. package/dist/esm/utils/mobileUpload/stateMachine/states/processing.js +68 -0
  57. package/dist/esm/utils/mobileUpload/stateMachine/states/processingFailed.js +3 -0
  58. package/dist/esm/utils/mobileUpload/stateMachine/states/uploading.js +58 -0
  59. package/dist/esm/utils/mobileUpload/stateMachine/types.js +1 -0
  60. package/dist/esm/utils/polling/index.js +5 -5
  61. package/dist/esm/version.json +1 -1
  62. package/dist/types/client/media-client.d.ts +3 -0
  63. package/dist/types/client/media-store/resolveAuth.d.ts +2 -2
  64. package/dist/types/client/mobile-upload.d.ts +11 -0
  65. package/dist/types/index.d.ts +4 -2
  66. package/dist/types/models/mobile-upload.d.ts +28 -0
  67. package/dist/types/utils/imageResizeModeToFileImageMode.d.ts +3 -0
  68. package/dist/types/utils/mobileUpload/error.d.ts +29 -0
  69. package/dist/types/utils/mobileUpload/helpers.d.ts +8 -0
  70. package/dist/types/utils/mobileUpload/index.d.ts +5 -0
  71. package/dist/types/utils/mobileUpload/servicesCache.d.ts +4 -0
  72. package/dist/types/utils/mobileUpload/stateMachine/index.d.ts +7 -0
  73. package/dist/types/utils/mobileUpload/stateMachine/states/error.d.ts +3 -0
  74. package/dist/types/utils/mobileUpload/stateMachine/states/processed.d.ts +3 -0
  75. package/dist/types/utils/mobileUpload/stateMachine/states/processing.d.ts +3 -0
  76. package/dist/types/utils/mobileUpload/stateMachine/states/processingFailed.d.ts +3 -0
  77. package/dist/types/utils/mobileUpload/stateMachine/states/uploading.d.ts +3 -0
  78. package/dist/types/utils/mobileUpload/stateMachine/types.d.ts +69 -0
  79. package/dist/types/utils/polling/errors.d.ts +1 -1
  80. package/dist/types/utils/polling/index.d.ts +8 -3
  81. package/package.json +6 -5
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.createMobileUploadService = createMobileUploadService;
9
+ exports.createMobileUploadStateMachine = void 0;
10
+
11
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
12
+
13
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
14
+
15
+ var _map = require("rxjs/operators/map");
16
+
17
+ var _xstate = require("xstate");
18
+
19
+ var _fileState = require("../../../models/file-state");
20
+
21
+ var _shouldFetchRemoteFileStates3 = require("../../shouldFetchRemoteFileStates");
22
+
23
+ var _helpers = require("../helpers");
24
+
25
+ var _uploading = require("./states/uploading");
26
+
27
+ var _processing = require("./states/processing");
28
+
29
+ var _processed = require("./states/processed");
30
+
31
+ var _processingFailed = require("./states/processingFailed");
32
+
33
+ var _error = require("./states/error");
34
+
35
+ var createMobileUploadStateMachine = function createMobileUploadStateMachine(dataloader, initialState, collectionName) {
36
+ return (0, _xstate.createMachine)({
37
+ // Initial state
38
+ initial: initialState.status,
39
+ // Context
40
+ context: {
41
+ currentFileState: initialState
42
+ },
43
+ // State definitions
44
+ states: {
45
+ uploading: _uploading.machineUploadingState,
46
+ processing: _processing.machineProcessingState,
47
+ processed: _processed.machineProcessedState,
48
+ processingFailed: _processingFailed.machineProcessingFailedState,
49
+ error: _error.machineErrorState
50
+ }
51
+ }, {
52
+ services: {
53
+ shouldFetchRemoteFileStates: function () {
54
+ var _shouldFetchRemoteFileStates2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(ctx) {
55
+ var currentFileState, mediaType, mimeType, preview;
56
+ return _regenerator.default.wrap(function _callee$(_context) {
57
+ while (1) {
58
+ switch (_context.prev = _context.next) {
59
+ case 0:
60
+ currentFileState = ctx.currentFileState;
61
+
62
+ if (!(0, _fileState.isProcessingFileState)(currentFileState)) {
63
+ _context.next = 4;
64
+ break;
65
+ }
66
+
67
+ mediaType = currentFileState.mediaType, mimeType = currentFileState.mimeType, preview = currentFileState.preview;
68
+ return _context.abrupt("return", (0, _shouldFetchRemoteFileStates3.shouldFetchRemoteFileStates)(mediaType, mimeType, preview));
69
+
70
+ case 4:
71
+ return _context.abrupt("return", false);
72
+
73
+ case 5:
74
+ case "end":
75
+ return _context.stop();
76
+ }
77
+ }
78
+ }, _callee);
79
+ }));
80
+
81
+ function shouldFetchRemoteFileStates(_x) {
82
+ return _shouldFetchRemoteFileStates2.apply(this, arguments);
83
+ }
84
+
85
+ return shouldFetchRemoteFileStates;
86
+ }(),
87
+ fetchRemoteFileStates: function fetchRemoteFileStates(ctx) {
88
+ return (0, _helpers.createMobileDownloadFileStream)(dataloader, ctx.currentFileState.id, collectionName, ctx.currentFileState.occurrenceKey).pipe((0, _map.map)(function (fileState) {
89
+ return {
90
+ type: 'REMOTE_FILESTATE_RESULT',
91
+ fileState: fileState
92
+ };
93
+ }));
94
+ }
95
+ }
96
+ });
97
+ };
98
+
99
+ exports.createMobileUploadStateMachine = createMobileUploadStateMachine;
100
+
101
+ function createMobileUploadService(machine) {
102
+ return (0, _xstate.interpret)(machine);
103
+ }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.machineErrorState = void 0;
7
+ var machineErrorState = {
8
+ type: 'final'
9
+ };
10
+ exports.machineErrorState = machineErrorState;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.machineProcessedState = void 0;
7
+ var machineProcessedState = {
8
+ type: 'final'
9
+ };
10
+ exports.machineProcessedState = machineProcessedState;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.machineProcessingState = void 0;
7
+
8
+ var _xstate = require("xstate");
9
+
10
+ var machineProcessingState = {
11
+ // Events
12
+ on: {
13
+ REMOTE_FILESTATE_PROCESSED: 'processed',
14
+ REMOTE_FILESTATE_PROCESSING_FAILED: 'processingFailed',
15
+ REMOTE_FILESTATE_ERROR: 'error'
16
+ },
17
+ // Initial sub state
18
+ initial: 'loading',
19
+ // Sub states definitions
20
+ states: {
21
+ loading: {
22
+ invoke: {
23
+ src: 'shouldFetchRemoteFileStates',
24
+ onDone: {
25
+ actions: (0, _xstate.send)(function (_, event) {
26
+ return {
27
+ // shouldFetchRemoteFileStates resolves a boolean
28
+ type: event.data ? 'REMOTE_FILESTATE_FETCH' : 'REMOTE_FILESTATE_BYPASS'
29
+ };
30
+ })
31
+ },
32
+ onError: 'idle'
33
+ },
34
+ on: {
35
+ REMOTE_FILESTATE_FETCH: 'fetchingRemoteFileStates',
36
+ REMOTE_FILESTATE_BYPASS: 'idle'
37
+ }
38
+ },
39
+ fetchingRemoteFileStates: {
40
+ invoke: {
41
+ src: 'fetchRemoteFileStates',
42
+ onDone: {
43
+ actions: (0, _xstate.send)(function (ctx) {
44
+ return {
45
+ type: ctx.currentFileState.status === 'processed' ? 'REMOTE_FILESTATE_PROCESSED' : 'REMOTE_FILESTATE_PROCESSING_FAILED'
46
+ };
47
+ })
48
+ },
49
+ onError: {
50
+ actions: [(0, _xstate.assign)({
51
+ currentFileState: function currentFileState(ctx, event) {
52
+ return {
53
+ status: 'error',
54
+ id: ctx.currentFileState.id,
55
+ occurrenceKey: ctx.currentFileState.occurrenceKey,
56
+ message: event.data.message
57
+ };
58
+ }
59
+ }), (0, _xstate.send)({
60
+ type: 'REMOTE_FILESTATE_ERROR'
61
+ })]
62
+ }
63
+ },
64
+ on: {
65
+ REMOTE_FILESTATE_RESULT: {
66
+ actions: (0, _xstate.assign)({
67
+ currentFileState: function currentFileState(_, event) {
68
+ return event.fileState;
69
+ }
70
+ })
71
+ }
72
+ }
73
+ },
74
+ idle: {}
75
+ }
76
+ };
77
+ exports.machineProcessingState = machineProcessingState;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.machineProcessingFailedState = void 0;
7
+ var machineProcessingFailedState = {
8
+ type: 'final'
9
+ };
10
+ exports.machineProcessingFailedState = machineProcessingFailedState;
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.machineUploadingState = void 0;
9
+
10
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
+
12
+ var _xstate = require("xstate");
13
+
14
+ var _fileState = require("../../../../models/file-state");
15
+
16
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
17
+
18
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
19
+
20
+ var machineUploadingState = {
21
+ // Events
22
+ on: {
23
+ UPLOAD_PROGRESS: [{
24
+ target: 'uploading',
25
+ cond: function cond(ctx, event) {
26
+ return (0, _fileState.isUploadingFileState)(ctx.currentFileState) && event.progress > ctx.currentFileState.progress;
27
+ },
28
+ actions: (0, _xstate.assign)({
29
+ currentFileState: function currentFileState(ctx, event) {
30
+ return _objectSpread(_objectSpread({}, ctx.currentFileState), {}, {
31
+ progress: event.progress
32
+ });
33
+ }
34
+ })
35
+ }, {
36
+ target: 'error'
37
+ }],
38
+ UPLOAD_END: {
39
+ target: 'processing',
40
+ actions: (0, _xstate.assign)({
41
+ currentFileState: function currentFileState(ctx) {
42
+ return (0, _fileState.isUploadingFileState)(ctx.currentFileState) && {
43
+ status: 'processing',
44
+ id: ctx.currentFileState.id,
45
+ occurrenceKey: ctx.currentFileState.occurrenceKey,
46
+ name: ctx.currentFileState.name,
47
+ size: ctx.currentFileState.size,
48
+ mediaType: ctx.currentFileState.mediaType,
49
+ mimeType: ctx.currentFileState.mimeType,
50
+ preview: ctx.currentFileState.preview,
51
+ createdAt: ctx.currentFileState.createdAt
52
+ } || ctx.currentFileState;
53
+ }
54
+ })
55
+ },
56
+ UPLOAD_ERROR: {
57
+ target: 'error',
58
+ actions: (0, _xstate.assign)({
59
+ currentFileState: function currentFileState(ctx, event) {
60
+ return {
61
+ status: 'error',
62
+ id: ctx.currentFileState.id,
63
+ message: event.message
64
+ };
65
+ }
66
+ })
67
+ }
68
+ }
69
+ };
70
+ exports.machineUploadingState = machineUploadingState;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
@@ -17,19 +17,18 @@ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/creat
17
17
 
18
18
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
19
19
 
20
- var _mediaFeatureFlags = require("@atlaskit/media-common/mediaFeatureFlags");
21
-
22
20
  var _errors = require("./errors");
23
21
 
24
22
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
25
23
 
26
24
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
27
25
 
26
+ // default polling options without using feature flags
28
27
  var defaultPollingOptions = {
29
- poll_intervalMs: (0, _mediaFeatureFlags.getMediaFeatureFlag)('poll_intervalMs'),
30
- poll_maxAttempts: (0, _mediaFeatureFlags.getMediaFeatureFlag)('poll_maxAttempts'),
31
- poll_backoffFactor: (0, _mediaFeatureFlags.getMediaFeatureFlag)('poll_backoffFactor'),
32
- poll_maxIntervalMs: (0, _mediaFeatureFlags.getMediaFeatureFlag)('poll_maxIntervalMs')
28
+ poll_intervalMs: 3000,
29
+ poll_maxAttempts: 30,
30
+ poll_backoffFactor: 1.25,
31
+ poll_maxIntervalMs: 200000
33
32
  };
34
33
  /**
35
34
  * This class encapsulates polling functionality with the following features:
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/media-client",
3
- "version": "14.1.0",
3
+ "version": "14.3.1",
4
4
  "sideEffects": false
5
5
  }
@@ -28,22 +28,12 @@ import { isMimeTypeSupportedByBrowser, getMediaTypeFromMimeType } from '@atlaski
28
28
  import { shouldFetchRemoteFileStates, shouldFetchRemoteFileStatesObservable } from '../../utils/shouldFetchRemoteFileStates';
29
29
  import { PollingFunction } from '../../utils/polling';
30
30
  import { isEmptyFile } from '../../utils/detectEmptyFile';
31
- import { getMediaFeatureFlag } from '@atlaskit/media-common/mediaFeatureFlags';
32
31
  export { isFileFetcherError, FileFetcherError } from './error';
33
32
  export class FileFetcherImpl {
34
33
  constructor(mediaStore) {
35
34
  _defineProperty(this, "createDownloadFileStream", (id, collectionName, occurrenceKey) => {
36
35
  const subject = createFileStateSubject();
37
- const {
38
- featureFlags
39
- } = this.mediaStore;
40
- const pollingOptions = {
41
- poll_intervalMs: getMediaFeatureFlag('poll_intervalMs', featureFlags),
42
- poll_maxAttempts: getMediaFeatureFlag('poll_maxAttempts', featureFlags),
43
- poll_backoffFactor: getMediaFeatureFlag('poll_backoffFactor', featureFlags),
44
- poll_maxIntervalMs: getMediaFeatureFlag('poll_maxIntervalMs', featureFlags)
45
- };
46
- const poll = new PollingFunction(pollingOptions); // ensure subject errors if polling exceeds max iterations or uncaught exception in executor
36
+ const poll = new PollingFunction(); // ensure subject errors if polling exceeds max iterations or uncaught exception in executor
47
37
 
48
38
  poll.onError = error => subject.error(error);
49
39
 
@@ -4,12 +4,14 @@ import { CollectionFetcher } from './collection-fetcher';
4
4
  import { FileFetcherImpl } from './file-fetcher';
5
5
  import { StargateClient } from './stargate-client';
6
6
  export class MediaClient {
7
+ // mobile upload is lazily loaded
7
8
  // Deprecated value introduced for backward compatibility with Context
8
9
  constructor(mediaClientConfig, featureFlags) {
9
10
  this.mediaClientConfig = mediaClientConfig;
10
11
  this.featureFlags = featureFlags;
11
12
  this.mediaStore = new MediaStore({
12
- authProvider: mediaClientConfig.authProvider
13
+ authProvider: mediaClientConfig.authProvider,
14
+ initialAuth: mediaClientConfig.initialAuth
13
15
  }, featureFlags);
14
16
  this.config = mediaClientConfig;
15
17
  this.collection = new CollectionFetcher(this.mediaStore);
@@ -34,6 +36,18 @@ export class MediaClient {
34
36
  return (await this.mediaStore.getImageMetadata(id, params)).metadata;
35
37
  }
36
38
 
39
+ async mobileUploadPromise() {
40
+ if (this.mobileUpload) {
41
+ return this.mobileUpload;
42
+ }
43
+
44
+ const module = await import(
45
+ /* webpackChunkName: "@atlaskit-internal_media-client-mobile-upload" */
46
+ './mobile-upload');
47
+ this.mobileUpload = new module.MobileUploadImpl(this.mediaStore);
48
+ return this.mobileUpload;
49
+ }
50
+
37
51
  on(event, listener) {
38
52
  this.eventEmitter.on(event, listener);
39
53
  }
@@ -1,11 +1,11 @@
1
1
  import { MediaStoreError } from './error';
2
2
  import { rejectTimeout } from '../../utils/setTimeoutPromise';
3
- export const AUTH_PROVIDER_TIMEOUT = 10000;
4
- export const resolveAuth = async (authProvider, authContext) => {
3
+ export const DEFAULT_AUTH_PROVIDER_TIMEOUT = 10000;
4
+ export const resolveAuth = async (authProvider, authContext, authProviderTimeout = DEFAULT_AUTH_PROVIDER_TIMEOUT) => {
5
5
  let auth;
6
6
 
7
7
  try {
8
- auth = await Promise.race([authProvider(authContext), rejectTimeout(AUTH_PROVIDER_TIMEOUT, new MediaStoreError('authProviderTimedOut'))]);
8
+ auth = await Promise.race([authProvider(authContext), rejectTimeout(authProviderTimeout, new MediaStoreError('authProviderTimedOut'))]);
9
9
  } catch (err) {
10
10
  if (err instanceof MediaStoreError) {
11
11
  throw err;
@@ -0,0 +1,80 @@
1
+ import { getMediaTypeFromMimeType } from '@atlaskit/media-common';
2
+ import { getFileStreamsCache } from '../file-streams-cache';
3
+ import { createFileDataloader } from '../utils/createFileDataLoader';
4
+ import { createServicesCache, createMobileUploadStateMachine, createMobileUploadService, createMobileFileStateSubject } from '../utils/mobileUpload';
5
+ export class MobileUploadImpl {
6
+ constructor(mediaStore) {
7
+ this.dataloader = createFileDataloader(mediaStore);
8
+ this.servicesCache = createServicesCache();
9
+ }
10
+
11
+ notifyUploadStart(event) {
12
+ const {
13
+ fileId,
14
+ collectionName,
15
+ occurrenceKey,
16
+ fileName,
17
+ fileSize,
18
+ fileMimetype,
19
+ preview,
20
+ createdAt
21
+ } = event;
22
+ const mediaType = getMediaTypeFromMimeType(fileMimetype);
23
+ const initialState = {
24
+ status: 'uploading',
25
+ id: fileId,
26
+ occurrenceKey,
27
+ name: fileName,
28
+ size: fileSize,
29
+ progress: 0,
30
+ mediaType,
31
+ mimeType: fileMimetype,
32
+ preview,
33
+ createdAt
34
+ };
35
+ const service = createMobileUploadService(createMobileUploadStateMachine(this.dataloader, initialState, collectionName));
36
+ const subject = createMobileFileStateSubject(service);
37
+ this.servicesCache.put(fileId, service);
38
+ getFileStreamsCache().set(fileId, subject);
39
+ }
40
+
41
+ notifyUploadProgress(event) {
42
+ const {
43
+ fileId,
44
+ progress
45
+ } = event;
46
+ const service = this.servicesCache.get(fileId);
47
+
48
+ if (service) {
49
+ service.send('UPLOAD_PROGRESS', {
50
+ progress
51
+ });
52
+ }
53
+ }
54
+
55
+ notifyUploadEnd(event) {
56
+ const {
57
+ fileId
58
+ } = event;
59
+ const service = this.servicesCache.get(fileId);
60
+
61
+ if (service) {
62
+ service.send('UPLOAD_END');
63
+ }
64
+ }
65
+
66
+ notifyUploadError(event) {
67
+ const {
68
+ fileId,
69
+ message
70
+ } = event;
71
+ const service = this.servicesCache.get(fileId);
72
+
73
+ if (service) {
74
+ service.send('UPLOAD_ERROR', {
75
+ message
76
+ });
77
+ }
78
+ }
79
+
80
+ }
@@ -10,6 +10,7 @@ export { request, RequestError, isRequestError, isRateLimitedError } from './uti
10
10
  export { isAbortedRequestError, mapResponseToJson, mapResponseToBlob, mapResponseToVoid, createUrl } from './utils/request/helpers';
11
11
  export { PollingFunction } from './utils/polling';
12
12
  export { isPollingError, PollingError } from './utils/polling/errors';
13
+ export { imageResizeModeToFileImageMode } from './utils/imageResizeModeToFileImageMode';
13
14
  export { FileFetcherImpl, FileFetcherError, isFileFetcherError } from './client/file-fetcher';
14
15
  export { CollectionFetcher } from './client/collection-fetcher';
15
16
  export { MediaClient } from './client/media-client';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export const imageResizeModeToFileImageMode = resizeMode => resizeMode === 'stretchy-fit' ? 'full-fit' : resizeMode;
@@ -0,0 +1,30 @@
1
+ import { BaseMediaClientError } from '../../models/errors';
2
+ export class MobileUploadError 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 isMobileUploadError(err) {
29
+ return err instanceof MobileUploadError;
30
+ }
@@ -0,0 +1,55 @@
1
+ import { ReplaySubject } from 'rxjs/ReplaySubject';
2
+ import { from } from 'rxjs/observable/from';
3
+ import { map } from 'rxjs/operators/map';
4
+ import { mapMediaItemToFileState } from '../../models/file-state';
5
+ import { createFileStateSubject } from '../createFileStateSubject';
6
+ import { isEmptyFile } from '../detectEmptyFile';
7
+ import { PollingFunction } from '../polling';
8
+ import { MobileUploadError } from './error';
9
+ export const createMobileFileStateSubject = service => {
10
+ const subject = new ReplaySubject(1);
11
+ from(service.start()).pipe(map(state => state.context.currentFileState)).subscribe(subject);
12
+ return subject;
13
+ };
14
+ export const createMobileDownloadFileStream = (dataloader, id, collectionName, occurrenceKey) => {
15
+ const subject = createFileStateSubject();
16
+ const poll = new PollingFunction(); // ensure subject errors if polling exceeds max iterations or uncaught exception in executor
17
+
18
+ poll.onError = error => subject.error(error);
19
+
20
+ poll.execute(async () => {
21
+ const response = await dataloader.load({
22
+ id,
23
+ collectionName
24
+ });
25
+
26
+ if (!response) {
27
+ throw new MobileUploadError('emptyItems', id, {
28
+ collectionName,
29
+ occurrenceKey
30
+ });
31
+ }
32
+
33
+ if (isEmptyFile(response)) {
34
+ throw new MobileUploadError('zeroVersionFile', id, {
35
+ collectionName,
36
+ occurrenceKey
37
+ });
38
+ }
39
+
40
+ const fileState = mapMediaItemToFileState(id, response);
41
+ subject.next(fileState);
42
+
43
+ switch (fileState.status) {
44
+ case 'processing':
45
+ // the only case for continuing polling, otherwise this function is run once only
46
+ poll.next();
47
+ break;
48
+
49
+ case 'processed':
50
+ subject.complete();
51
+ break;
52
+ }
53
+ });
54
+ return subject;
55
+ };
@@ -0,0 +1,4 @@
1
+ export { isMobileUploadError, MobileUploadError } from './error';
2
+ export { createServicesCache } from './servicesCache';
3
+ export { createMobileUploadService, createMobileUploadStateMachine } from './stateMachine';
4
+ export { createMobileFileStateSubject } from './helpers';
@@ -0,0 +1,4 @@
1
+ import { LRUCache } from 'lru-fast';
2
+ export function createServicesCache() {
3
+ return new LRUCache(100);
4
+ }
@@ -0,0 +1,52 @@
1
+ import { map } from 'rxjs/operators/map';
2
+ import { createMachine, interpret } from 'xstate';
3
+ import { isProcessingFileState } from '../../../models/file-state';
4
+ import { shouldFetchRemoteFileStates } from '../../shouldFetchRemoteFileStates';
5
+ import { createMobileDownloadFileStream } from '../helpers';
6
+ import { machineUploadingState } from './states/uploading';
7
+ import { machineProcessingState } from './states/processing';
8
+ import { machineProcessedState } from './states/processed';
9
+ import { machineProcessingFailedState } from './states/processingFailed';
10
+ import { machineErrorState } from './states/error';
11
+ export const createMobileUploadStateMachine = (dataloader, initialState, collectionName) => createMachine({
12
+ // Initial state
13
+ initial: initialState.status,
14
+ // Context
15
+ context: {
16
+ currentFileState: initialState
17
+ },
18
+ // State definitions
19
+ states: {
20
+ uploading: machineUploadingState,
21
+ processing: machineProcessingState,
22
+ processed: machineProcessedState,
23
+ processingFailed: machineProcessingFailedState,
24
+ error: machineErrorState
25
+ }
26
+ }, {
27
+ services: {
28
+ shouldFetchRemoteFileStates: async ctx => {
29
+ const {
30
+ currentFileState
31
+ } = ctx;
32
+
33
+ if (isProcessingFileState(currentFileState)) {
34
+ const {
35
+ mediaType,
36
+ mimeType,
37
+ preview
38
+ } = currentFileState;
39
+ return shouldFetchRemoteFileStates(mediaType, mimeType, preview);
40
+ }
41
+
42
+ return false;
43
+ },
44
+ fetchRemoteFileStates: ctx => createMobileDownloadFileStream(dataloader, ctx.currentFileState.id, collectionName, ctx.currentFileState.occurrenceKey).pipe(map(fileState => ({
45
+ type: 'REMOTE_FILESTATE_RESULT',
46
+ fileState
47
+ })))
48
+ }
49
+ });
50
+ export function createMobileUploadService(machine) {
51
+ return interpret(machine);
52
+ }
@@ -0,0 +1,3 @@
1
+ export const machineErrorState = {
2
+ type: 'final'
3
+ };
@@ -0,0 +1,3 @@
1
+ export const machineProcessedState = {
2
+ type: 'final'
3
+ };