@aws-amplify/storage
Version:
Storage category of aws-amplify
86 lines (84 loc) • 3.67 kB
JavaScript
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
Object.defineProperty(exports, "__esModule", { value: true });
exports.removeCachedUpload = exports.cacheMultipartUpload = exports.getUploadsCacheKey = exports.findCachedUploadParts = void 0;
const core_1 = require("@aws-amplify/core");
const constants_1 = require("../../../utils/constants");
const client_1 = require("../../../utils/client");
const utils_1 = require("../../../../../utils");
const ONE_HOUR = 1000 * 60 * 60;
/**
* Find the cached multipart upload id and get the parts that have been uploaded
* with ListParts API. If the cached upload is expired(1 hour), return null.
*/
const findCachedUploadParts = async ({ cacheKey, s3Config, bucket, finalKey, }) => {
const cachedUploads = await listCachedUploadTasks(core_1.defaultStorage);
if (!cachedUploads[cacheKey] ||
cachedUploads[cacheKey].lastTouched < Date.now() - ONE_HOUR // Uploads are cached for 1 hour
) {
return null;
}
const cachedUpload = cachedUploads[cacheKey];
cachedUpload.lastTouched = Date.now();
await core_1.defaultStorage.setItem(constants_1.UPLOADS_STORAGE_KEY, JSON.stringify(cachedUploads));
try {
const { Parts = [] } = await (0, client_1.listParts)(s3Config, {
Bucket: bucket,
Key: finalKey,
UploadId: cachedUpload.uploadId,
});
return {
parts: Parts,
uploadId: cachedUpload.uploadId,
};
}
catch (e) {
utils_1.logger.debug('failed to list cached parts, removing cached upload.');
await (0, exports.removeCachedUpload)(cacheKey);
return null;
}
};
exports.findCachedUploadParts = findCachedUploadParts;
const listCachedUploadTasks = async (kvStorage) => {
try {
return JSON.parse((await kvStorage.getItem(constants_1.UPLOADS_STORAGE_KEY)) ?? '{}');
}
catch (e) {
utils_1.logger.debug('failed to parse cached uploads record.');
return {};
}
};
/**
* Get the cache key of a multipart upload. Data source cached by different: size, content type, bucket, access level,
* key. If the data source is a File instance, the upload is additionally indexed by file name and last modified time.
* So the library always created a new multipart upload if the file is modified.
*/
const getUploadsCacheKey = ({ file, size, contentType, bucket, accessLevel, key, }) => {
const resolvedContentType = contentType ?? file?.type ?? 'application/octet-stream';
const levelStr = accessLevel === 'guest' ? 'public' : accessLevel;
const baseId = `${size}_${resolvedContentType}_${bucket}_${levelStr}_${key}`;
if (file) {
return `${file.name}_${file.lastModified}_${baseId}`;
}
else {
return baseId;
}
};
exports.getUploadsCacheKey = getUploadsCacheKey;
const cacheMultipartUpload = async (cacheKey, fileMetadata) => {
const cachedUploads = await listCachedUploadTasks(core_1.defaultStorage);
cachedUploads[cacheKey] = {
...fileMetadata,
lastTouched: Date.now(),
};
await core_1.defaultStorage.setItem(constants_1.UPLOADS_STORAGE_KEY, JSON.stringify(cachedUploads));
};
exports.cacheMultipartUpload = cacheMultipartUpload;
const removeCachedUpload = async (cacheKey) => {
const cachedUploads = await listCachedUploadTasks(core_1.defaultStorage);
delete cachedUploads[cacheKey];
await core_1.defaultStorage.setItem(constants_1.UPLOADS_STORAGE_KEY, JSON.stringify(cachedUploads));
};
exports.removeCachedUpload = removeCachedUpload;
//# sourceMappingURL=uploadCache.js.map
;