import { Signal } from '@vobs/reactivity'; import { RequestOptions, HTTPClient } from '@vobs/http'; import { InjectionKey, VobsPlugin } from '@vobs/vobs'; type UploadStatus = 'pending' | 'uploading' | 'success' | 'error' | 'cancelled'; type UploadFile = Blob & { readonly name?: string; readonly lastModified?: number; }; type UploadMetadata = Readonly>; interface UploadTask { readonly id: string; readonly file: UploadFile; readonly progress: Signal; readonly status: Signal; readonly error: Signal; readonly result: Signal; readonly promise: Promise; cancel(): void; retry(): Promise; } interface UploadTaskOptions { readonly id?: string; readonly fieldName?: string; readonly fileName?: string; readonly metadata?: UploadMetadata; readonly headers?: HeadersInit; readonly timeout?: number; readonly retry?: number; readonly retryDelay?: RequestOptions['retryDelay']; readonly shouldRetry?: RequestOptions['shouldRetry']; readonly response?: (data: unknown, task: UploadTask) => Result | PromiseLike; } interface UploadOptions extends Omit, 'id' | 'metadata' | 'response'> { readonly http: HTTPClient; readonly url: string; readonly method?: 'POST' | 'PUT' | 'PATCH'; readonly fieldName?: string; readonly metadata?: UploadMetadata; readonly accept?: string | readonly string[]; readonly maxFileSize?: number; readonly concurrency?: number; readonly idFactory?: () => string; readonly response?: (data: unknown, task: UploadTask) => Result | PromiseLike; } interface UploadPluginOptions extends Omit, 'http'> { readonly http?: HTTPClient; readonly upload?: UploadContext; } interface UploadContext { readonly tasks: Signal[]>; upload(file: UploadFile, options?: UploadTaskOptions): UploadTask; uploadAll(files: Iterable, options?: UploadTaskOptions): readonly UploadTask[]; clearCompleted(): void; dispose(): void; } type UploadErrorCode = 'UPLOAD_CONTEXT_MISSING' | 'UPLOAD_CONTEXT_DISPOSED' | 'UPLOAD_UNAVAILABLE' | 'INVALID_UPLOAD_OPTIONS' | 'INVALID_FILE' | 'FILE_TYPE_UNSUPPORTED' | 'FILE_TOO_LARGE' | 'UPLOAD_FAILED' /** * 响应解析/映射失败 —— 与 `UPLOAD_FAILED`(传输失败)**必须分开**: * 走到这一步说明服务端已经收到并可能已落库,盲目重传在默认 POST 下等于重复写入。 */ | 'UPLOAD_RESPONSE_INVALID'; declare class UploadError extends Error { readonly code: UploadErrorCode; readonly cause: unknown; constructor(code: UploadErrorCode, message: string, cause?: unknown); } declare const UPLOAD_KEY: InjectionKey>; declare function createUpload(options: UploadOptions): UploadContext; declare function uploadPlugin(options: UploadPluginOptions): VobsPlugin; declare function useUpload(): UploadContext; export { UPLOAD_KEY, type UploadContext, UploadError, type UploadErrorCode, type UploadFile, type UploadMetadata, type UploadOptions, type UploadPluginOptions, type UploadStatus, type UploadTask, type UploadTaskOptions, createUpload, uploadPlugin, useUpload };