sharding-downloader
Version:
This project downloads files in the browser,Support large file sharding and IndexedDB(大文件分片下载)
307 lines (285 loc) • 8.79 kB
TypeScript
export declare const Callbacks: {
FAILED: string;
PROGRESS: string;
SUCCESS: string;
CHANGE: string;
CANCELLED: string;
};
declare class Chunk {
/** chunk所在file的实例 */
parent: FileContext;
/** file相关配置 */
options: FileOptions;
/** chunk的索引 */
index: number;
/** 下载文件的Obs地址,或者下载标识 */
url: string;
/** 文件大小 */
fileSize: number;
/** 分片大小 */
chunkSize: number;
/** chunk所在文件流的位置起点 */
startByte: number;
/** chunk所在文件流的位置终点 */
endByte: number;
/** chunk大小 */
size: number;
/** chunk状态 */
status: string;
/** 重试次数 */
maxRetries: number;
/** */
request: any;
/** 重试间隔计时器 */
timer: undefined | number;
/** 下载进度 */
progress: number;
/** 已下载大小 */
loaded: number;
constructor(index: number, parent: FileContext, options: FileOptions);
handleProgress: (...args: any[]) => void;
send(): Promise<Blob>;
cancel(): void;
setSuccess(): void;
}
declare class DBWrapper {
_store: IndexedDBWrapper | MemoryStorage;
type: 'IndexedDB' | 'Memory';
constructor(version?: number, dbName?: string);
checkChunk(fileId: string, chunkIndex: number): Promise<unknown>;
saveChunk(fileId: string, chunkIndex: number, chunkSize: number, chunkData: Blob): Promise<unknown>;
updateMetadata(file: FileContext, downloadedChunks: number[]): Promise<unknown>;
getMetadata(fileId: string): Promise<FileMetadata | null>;
getChunks(fileId: string): Promise<StorageChunk[]>;
cleanupFileData(fileId: string): Promise<unknown>;
cleanupExpiredChunks(): Promise<unknown>;
close(): void;
}
export declare class Downloader {
options: DownloaderOptions;
private event;
storage: DBWrapper;
fileList: FileContext[];
constructor(options: UserDownloaderOptions);
on(name: string, fn: Function): void;
emit(name: string, ...args: any[]): void;
setOption(options: UserDownloaderOptions): void;
start(url: string): Promise<void>;
_addFile(file: FileContext): void;
}
export declare type DownloaderOptions = {
/** IndexedDB version */
storageVersion: number;
/**
* indexedDB name
*/
storageName: string;
/**
* 分段下载接口
*/
action: string;
/** 自定义data */
data: Record<string, any>;
/**
* 自定义headers
*/
headers: Record<string, string>;
/**
* 分片大小,单位是bit
*/
chunkSize: number;
/**
* 接口并发数
*/
threads: number;
/**
* 自定义下载接口
*/
customRequest: Request_2;
/**
* 最大自动重试次数
*/
maxRetries: number;
/**
* 重试间隔时间,单位是ms
*/
retryInterval: number;
/**
* 接口成功判断逻辑,返回true为接口成功
* @param data
* @returns
*/
requestSucceed: (data: Blob | object) => Promise<boolean>;
/**
* 是否分片下载
*/
isPart: boolean;
};
declare class FileContext {
/** 配置 */
private options;
/** 下载实例 */
private downloader;
/** 存储store */
private storage;
/** 文件id */
id: string;
/** 文件名称 */
name: string;
/** 文件大小 */
size: number;
/** 文件唯一标识 */
etag: string;
/** 文件状态 */
status: TypeFileStatus;
/** 下载成功后生成的前端地址 */
link: string;
/** 分片大小 */
chunkSize: number;
/** 文件obs地址,或者文件下载标识 */
url: string;
/** 下载接口 */
action: string;
/** 文件下载进度 */
progress: number;
/** 文件已经下载的大小(bit) */
loadedSize: number;
/** 分片chunk数组 */
chunks: Chunk[];
/** 总分片数 */
totalChunks: number;
/** 已经下载chunk索引值 */
downloaded: Set<number>;
/** 取消获取文件元信息abort */
private metaAbort;
constructor(options: FileOptions, downloader: Downloader);
get renderSize(): string;
get renderLoadedSize(): string;
private changeStatus;
private createChunks;
private getMetadata;
private start;
private downloadPart;
private downloadChunks;
private downloadFull;
_updateProgress(): void;
private mergeFilePart;
generateBlobUrl(blob: Blob): string;
revokeBlobUrl(): void;
cancel(): void;
pause(): void;
retry(): void;
resume: () => void;
}
export declare type FileItem = Pick<FileContext, 'id' | 'chunkSize' | 'link' | 'loadedSize' | 'progress' | 'name' | 'status' | 'etag' | 'size' | 'url' | 'loadedSize' | 'totalChunks' | 'renderSize' | 'renderLoadedSize' | 'resume' | 'pause' | 'retry' | 'generateBlobUrl' | 'revokeBlobUrl'>;
declare type FileMetadata = {
fileId: string;
fileName: string;
totalSize: number;
chunkSize: number;
totalChunks: number;
action: string;
url: string;
downloadedChunks: number[];
updateAt: number;
};
declare type FileOptions = DownloaderOptions & {
url: string;
};
export declare const FileStatus: {
INIT: string;
READY: string;
DOWNLOADING: string;
DOWNLOADED: string;
CANCELLED: string;
SUCCESS: string;
FAILED: string;
};
declare class IndexedDBWrapper {
dbName: string;
version: number;
db: IDBDatabase | null;
constructor(version?: number, dbName?: string);
init(): Promise<unknown>;
transaction(storeName: 'chunks' | 'metadata', mode?: IDBTransactionMode): Promise<IDBObjectStore>;
checkChunk(fileId: string, chunkIndex: number): Promise<unknown>;
saveChunk(fileId: string, chunkIndex: number, chunkSize: number, chunkData: Blob): Promise<unknown>;
updateMetadata(file: FileContext, downloadedChunks: number[]): Promise<unknown>;
getMetadata(fileId: string): Promise<FileMetadata>;
getChunks(fileId: string): Promise<StorageChunk[]>;
cleanupFileData(fileId: string): Promise<unknown>;
cleanupExpiredChunks(): Promise<unknown>;
close(): void;
}
declare class MemoryStorage {
private store;
constructor();
checkChunk(fileId: string, chunkIndex: number): Promise<unknown>;
saveChunk(fileId: string, chunkIndex: number, chunkSize: number, chunkData: Blob): Promise<unknown>;
updateMetadata(file: FileContext, downloadedChunks: number[]): Promise<void>;
getMetadata(fileId: string): Promise<FileMetadata | null>;
getChunks(fileId: string): Promise<StorageChunk[]>;
cleanupFileData(fileId: string): Promise<unknown>;
cleanupExpiredChunks(): Promise<unknown>;
close(): void;
}
declare function request(options: RequestOptions): RequestReturn;
declare type Request_2 = typeof request;
export { Request_2 as Request }
export declare type RequestHeaders = {
'content-length': string;
'content-range': string;
'content-disposition': string;
etag: string;
[key: string]: string | undefined;
};
export declare type RequestOptions = {
/**
* 分片索引
*/
index?: number;
/** 下载接口地址 */
action: string;
/** 接口method类型 */
method?: 'POST' | 'GET' | 'post' | 'get';
/** 自定义上传参数 */
data: {
url: string;
index?: number;
[key: string]: any;
};
/** 自定义headers */
headers: {
Range?: string;
[key: string]: string | undefined;
};
/** 接口返回类型 */
responseType?: XMLHttpRequestResponseType;
/** 跨域是否支持携带凭证 */
withCredentials?: boolean;
/** 下载进度回调 */
onProgress?: (e: ProgressEvent) => void;
/** 下载成功回调 */
onSuccess?: (response: RequestResponse) => void;
/** 下载失败回调 */
onFail?: (error: Error, request?: any) => void;
};
export declare type RequestResponse = {
data: Blob | object;
status: number;
headers: RequestHeaders;
};
export declare type RequestReturn = {
abort: () => void;
canceled?: boolean;
};
declare type StorageChunk = {
fileId: string;
chunkIndex: number;
chunkSize: number;
data: Blob;
updateAt: number;
};
declare type TypeFileStatus = (typeof FileStatus)[keyof typeof FileStatus];
export declare type UserDownloaderOptions = Partial<DownloaderOptions>;
export { }