@mux/upchunk
Version:
Dead simple chunked file uploads using Fetch
149 lines (148 loc) • 5.44 kB
TypeScript
import type { XhrHeaders, XhrResponse } from 'xhr';
declare type XhrResponseLike = Partial<XhrResponse> & Pick<XhrResponse, 'statusCode'>;
export declare const isValidChunkSize: (chunkSize: any, { minChunkSize, maxChunkSize, }?: {
minChunkSize?: number | undefined;
maxChunkSize?: number | undefined;
}) => chunkSize is number | null | undefined;
export declare const getChunkSizeError: (chunkSize: any, { minChunkSize, maxChunkSize, }?: {
minChunkSize?: number | undefined;
maxChunkSize?: number | undefined;
}) => TypeError;
export declare type ChunkedStreamIterableOptions = {
defaultChunkSize?: number;
minChunkSize?: number;
maxChunkSize?: number;
};
export interface ChunkedIterable extends AsyncIterable<Blob> {
chunkSize: number;
readonly chunkByteSize: number;
readonly minChunkSize: number;
readonly maxChunkSize: number;
readonly error: Error | undefined;
}
export declare class ChunkedStreamIterable implements ChunkedIterable {
protected readableStream: ReadableStream<Uint8Array | Blob>;
protected _chunkSize: number | undefined;
protected defaultChunkSize: number;
protected _error: Error | undefined;
readonly minChunkSize: number;
readonly maxChunkSize: number;
constructor(readableStream: ReadableStream<Uint8Array | Blob>, options?: ChunkedStreamIterableOptions);
get chunkSize(): number;
set chunkSize(value: number);
get chunkByteSize(): number;
get error(): Error | undefined;
[Symbol.asyncIterator](): AsyncIterator<Blob>;
}
export declare class ChunkedFileIterable implements ChunkedIterable {
protected file: File;
protected _chunkSize: number | undefined;
protected defaultChunkSize: number;
protected _error: Error | undefined;
readonly minChunkSize: number;
readonly maxChunkSize: number;
constructor(file: File, options?: ChunkedStreamIterableOptions);
get chunkSize(): number;
set chunkSize(value: number);
get chunkByteSize(): number;
get error(): Error | undefined;
[Symbol.asyncIterator](): AsyncIterator<Blob>;
}
/**
* Checks if an upload chunk was partially received (HTTP 308) and needs a retry.
* Validates against the 'Range' header to ensure the full chunk was processed.
*/
export declare const isIncompleteChunkUploadNeedingRetry: (res: XhrResponseLike | undefined, _options?: any) => res is XhrResponseLike;
declare type EventName = 'attempt' | 'attemptFailure' | 'chunkSuccess' | 'error' | 'offline' | 'online' | 'progress' | 'success';
declare type AllowedMethods = 'PUT' | 'POST' | 'PATCH';
export interface UpChunkOptions {
endpoint: string | ((file?: File) => Promise<string>);
file: File;
method?: AllowedMethods;
headers?: XhrHeaders | (() => XhrHeaders) | (() => Promise<XhrHeaders>);
maxFileSize?: number;
chunkSize?: number;
attempts?: number;
delayBeforeAttempt?: number;
retryCodes?: number[];
dynamicChunkSize?: boolean;
maxChunkSize?: number;
minChunkSize?: number;
useLargeFileWorkaround?: boolean;
}
export declare class UpChunk {
static createUpload(options: UpChunkOptions): UpChunk;
endpoint: string | ((file?: File) => Promise<string>);
file: File;
headers: XhrHeaders | (() => XhrHeaders) | (() => Promise<XhrHeaders>);
method: AllowedMethods;
attempts: number;
delayBeforeAttempt: number;
retryCodes: number[];
dynamicChunkSize: boolean;
protected chunkedIterable: ChunkedIterable;
protected chunkedIterator: AsyncIterator<Blob, any, undefined>;
protected pendingChunk?: Blob;
private chunkCount;
private maxFileBytes;
private endpointValue;
private totalChunks;
private attemptCount;
private _offline;
private _paused;
private success;
private currentXhr?;
private lastChunkStart;
private nextChunkRangeStart;
private eventTarget;
constructor(options: UpChunkOptions);
protected get maxChunkSize(): number;
protected get minChunkSize(): number;
get chunkSize(): number;
set chunkSize(value: number);
get chunkByteSize(): number;
get totalChunkSize(): number;
/**
* Subscribe to an event
*/
on(eventName: EventName, fn: (event: CustomEvent) => void): void;
/**
* Subscribe to an event once
*/
once(eventName: EventName, fn: (event: CustomEvent) => void): void;
/**
* Unsubscribe to an event
*/
off(eventName: EventName, fn: (event: CustomEvent) => void): void;
get offline(): boolean;
get paused(): boolean;
abort(): void;
pause(): void;
resume(): void;
get successfulPercentage(): number;
/**
* Dispatch an event
*/
private dispatch;
/**
* Validate options and throw errors if expectations are violated.
*/
private validateOptions;
/**
* Endpoint can either be a URL or a function that returns a promise that resolves to a string.
*/
private getEndpoint;
private xhrPromise;
/**
* Send chunk of the file with appropriate headers
*/
protected sendChunk(chunk: Blob): Promise<XhrResponse>;
protected sendChunkWithRetries(chunk: Blob): Promise<boolean>;
/**
* Manage the whole upload by calling getChunk & sendChunk
* handle errors & retries and dispatch events
*/
private sendChunks;
}
export declare function createUpload(options: UpChunkOptions): UpChunk;
export {};