{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { getCurrentOwner, onDispose, state, type Signal } from '@vobs/reactivity'\nimport { HTTP_KEY, type HTTPClient, type HTTPProgress, type RequestOptions } from '@vobs/http'\nimport { createInjectionKey, inject, type InjectionKey, type VobsPlugin } from '@vobs/vobs'\n\nexport type UploadStatus = 'pending' | 'uploading' | 'success' | 'error' | 'cancelled'\n\nexport type UploadFile = Blob & { readonly name?: string; readonly lastModified?: number }\n\nexport type UploadMetadata = Readonly<Record<string, string | number | boolean | Blob | null | undefined>>\n\nexport interface UploadTask<Result = unknown> {\n  readonly id: string\n  readonly file: UploadFile\n  readonly progress: Signal<number>\n  readonly status: Signal<UploadStatus>\n  readonly error: Signal<UploadError | null>\n  readonly result: Signal<Result | null>\n  readonly promise: Promise<Result | null>\n  cancel(): void\n  retry(): Promise<Result | null>\n}\n\nexport interface UploadTaskOptions<Result = unknown> {\n  readonly id?: string\n  readonly fieldName?: string\n  readonly fileName?: string\n  readonly metadata?: UploadMetadata\n  readonly headers?: HeadersInit\n  readonly timeout?: number\n  readonly retry?: number\n  readonly retryDelay?: RequestOptions['retryDelay']\n  readonly shouldRetry?: RequestOptions['shouldRetry']\n  readonly response?: (data: unknown, task: UploadTask<Result>) => Result | PromiseLike<Result>\n}\n\nexport interface UploadOptions<Result = unknown> extends Omit<UploadTaskOptions<Result>, 'id' | 'metadata' | 'response'> {\n  readonly http: HTTPClient\n  readonly url: string\n  readonly method?: 'POST' | 'PUT' | 'PATCH'\n  readonly fieldName?: string\n  readonly metadata?: UploadMetadata\n  readonly accept?: string | readonly string[]\n  readonly maxFileSize?: number\n  readonly concurrency?: number\n  readonly idFactory?: () => string\n  readonly response?: (data: unknown, task: UploadTask<Result>) => Result | PromiseLike<Result>\n}\n\nexport interface UploadPluginOptions<Result = unknown> extends Omit<UploadOptions<Result>, 'http'> {\n  readonly http?: HTTPClient\n  readonly upload?: UploadContext<Result>\n}\n\nexport interface UploadContext<Result = unknown> {\n  readonly tasks: Signal<readonly UploadTask<Result>[]>\n  upload(file: UploadFile, options?: UploadTaskOptions<Result>): UploadTask<Result>\n  uploadAll(files: Iterable<UploadFile>, options?: UploadTaskOptions<Result>): readonly UploadTask<Result>[]\n  clearCompleted(): void\n  dispose(): void\n}\n\nexport type UploadErrorCode =\n  | 'UPLOAD_CONTEXT_MISSING'\n  | 'UPLOAD_CONTEXT_DISPOSED'\n  | 'UPLOAD_UNAVAILABLE'\n  | 'INVALID_UPLOAD_OPTIONS'\n  | 'INVALID_FILE'\n  | 'FILE_TYPE_UNSUPPORTED'\n  | 'FILE_TOO_LARGE'\n  | 'UPLOAD_FAILED'\n  /**\n   * 响应解析/映射失败 —— 与 `UPLOAD_FAILED`（传输失败）**必须分开**：\n   * 走到这一步说明服务端已经收到并可能已落库，盲目重传在默认 POST 下等于重复写入。\n   */\n  | 'UPLOAD_RESPONSE_INVALID'\n\nexport class UploadError extends Error {\n  readonly code: UploadErrorCode\n  readonly cause: unknown\n\n  constructor(code: UploadErrorCode, message: string, cause?: unknown) {\n    super(message)\n    this.name = 'UploadError'\n    this.code = code\n    this.cause = cause\n  }\n}\n\n// 应用注入键不携带调用方的 Result 泛型，useUpload<T>() 在读取时恢复该类型。\nexport const UPLOAD_KEY: InjectionKey<UploadContext<any>> = createInjectionKey<UploadContext<any>>('vobs.upload')\n\nexport function createUpload<Result = unknown>(options: UploadOptions<Result>): UploadContext<Result> {\n  validateOptions(options)\n  const fieldName = options.fieldName ?? 'file'\n  const concurrency = options.concurrency ?? 3\n  const tasks = state<readonly UploadTask<Result>[]>([])\n  const createdTasks = new Set<InternalUploadTask<Result>>()\n  const queue: Array<() => void> = []\n  let nextId = 0\n  let active = 0\n  let disposed = false\n\n  const context: UploadContext<Result> = {\n    tasks,\n\n    upload(file, taskOptions = {}): UploadTask<Result> {\n      ensureActive()\n      validateFile(file)\n      const id = taskOptions.id ?? options.idFactory?.() ?? `upload-${++nextId}`\n      if (typeof id !== 'string' || id.trim() === '') {\n        throw new UploadError('INVALID_UPLOAD_OPTIONS', 'Vobs Upload: task id 必须是非空字符串')\n      }\n      if (tasks.value.some(task => task.id === id)) {\n        throw new UploadError('INVALID_UPLOAD_OPTIONS', `Vobs Upload: 已存在任务 ${id}`)\n      }\n      const task = createTask(file, id, taskOptions)\n      createdTasks.add(task)\n      tasks.value = Object.freeze([...tasks.value, task])\n      enqueue(() => task.__run())\n      return task\n    },\n\n    uploadAll(files, taskOptions = {}): readonly UploadTask<Result>[] {\n      ensureActive()\n      return [...files].map(file => context.upload(file, taskOptions))\n    },\n\n    clearCompleted(): void {\n      ensureActive()\n      const retained = tasks.value.filter(task => (\n        task.status.value === 'pending' || task.status.value === 'uploading'\n      ))\n      tasks.value = Object.freeze(retained)\n      /*\n       * 清掉的行必须**同时**从 createdTasks 里摘掉并销毁信号。\n       *\n       * 原来只缩短公开数组：已完成的任务对象、它的 4 个信号、以及 `File` 引用会一直被\n       * `createdTasks` 强引用到 `dispose()` —— 长期开着的上传面板等于单调泄漏（报告 upload high）。\n       */\n      const retainedSet = new Set<UploadTask<Result>>(retained)\n      for (const task of createdTasks) {\n        if (retainedSet.has(task)) continue\n        createdTasks.delete(task)\n        task.__dispose()\n      }\n    },\n\n    dispose(): void {\n      if (disposed) return\n      disposed = true\n      /*\n       * 取消**所有创建过的任务**，而不是只遍历公开的 `tasks.value`。\n       *\n       * `tasks` 是公开可写的 Signal：调用方（或任何拿到上下文的代码）把它写成 `[]` 之后，\n       * 原来 dispose 就一个都取消不到 —— 在途上传继续跑，`await task.promise` **永久挂起**\n       * （报告探针 G：HUNG、status 卡在 uploading）。createdTasks 才是\"在途任务\"的真相来源。\n       */\n      for (const task of createdTasks) {\n        task.cancel()\n        task.__dispose()\n      }\n      createdTasks.clear()\n      queue.length = 0\n      tasks.value = Object.freeze([])\n      tasks.dispose()\n    }\n  }\n\n  if (getCurrentOwner()) onDispose(context.dispose)\n  return context\n\n  function createTask(file: UploadFile, id: string, taskOptions: UploadTaskOptions<Result>): InternalUploadTask<Result> {\n    const progress = state(0)\n    const status = state<UploadStatus>('pending')\n    // 类型收窄成 UploadError：调用方要靠 `.code` 区分\"能不能安全重传\"（见 UPLOAD_RESPONSE_INVALID）\n    const error = state<UploadError | null>(null)\n    const result = state<Result | null>(null)\n    let controller: AbortController | undefined\n    let settle: ((value: Result | null) => void) | undefined\n    let promise = createPromise()\n    let running = false\n\n    const task: InternalUploadTask<Result> = {\n      id,\n      file,\n      progress,\n      status,\n      error,\n      result,\n      get promise(): Promise<Result | null> { return promise },\n\n      cancel(): void {\n        if (status.value !== 'pending' && status.value !== 'uploading') return\n        status.value = 'cancelled'\n        controller?.abort()\n        settle?.(null)\n        settle = undefined\n      },\n\n      retry(): Promise<Result | null> {\n        ensureActive()\n        if (status.value === 'pending' || status.value === 'uploading') return promise\n        if (status.value === 'success') return promise\n        progress.value = 0\n        error.value = null\n        result.value = null\n        status.value = 'pending'\n        promise = createPromise()\n        enqueue(() => task.__run())\n        return promise\n      },\n\n      __run(): Promise<void> {\n        if (disposed || status.value !== 'pending' || running) return Promise.resolve()\n        running = true\n        controller = new AbortController()\n        status.value = 'uploading'\n        return send().finally(() => {\n          running = false\n          controller = undefined\n        })\n      },\n\n      __dispose(): void {\n        progress.dispose()\n        status.dispose()\n        error.dispose()\n        result.dispose()\n      }\n    }\n    return task\n\n    function createPromise(): Promise<Result | null> {\n      return new Promise(resolve => { settle = resolve })\n    }\n\n    async function send(): Promise<void> {\n      try {\n        const response = await options.http.request({\n          url: options.url,\n          method: options.method ?? 'POST',\n          body: createFormData(file, id, taskOptions),\n          headers: taskOptions.headers ?? options.headers,\n          timeout: taskOptions.timeout ?? options.timeout,\n          retry: taskOptions.retry ?? options.retry,\n          retryDelay: taskOptions.retryDelay ?? options.retryDelay,\n          shouldRetry: taskOptions.shouldRetry ?? options.shouldRetry,\n          signal: controller?.signal,\n          onUploadProgress: value => updateProgress(value)\n        })\n        if (isCancelled() || disposed) return\n        const mapper = taskOptions.response ?? options.response ?? ((data: unknown) => data as Result)\n        let mapped: Result\n        try {\n          mapped = await mapper(response.data, task)\n        } catch (reason) {\n          /*\n           * 请求**已经成功**，失败的只是我们这侧的响应解析。必须与传输失败分开报：\n           * 两者都归成 UPLOAD_FAILED 的话，调用方/重试 UI 分不清\"能不能安全重传\" ——\n           * 而默认 POST 非幂等，服务端已落库时的重传就是静默重复写入。\n           */\n          if (reason instanceof UploadError) throw reason\n          throw new UploadError(\n            'UPLOAD_RESPONSE_INVALID',\n            `Vobs Upload: ${fileName(file, id)} 的响应解析失败（文件可能已被服务端接收，不要盲目重传）`,\n            reason\n          )\n        }\n        if (isCancelled() || disposed) return\n        progress.value = 100\n        result.value = mapped\n        status.value = 'success'\n        settle?.(mapped)\n        settle = undefined\n      } catch (reason) {\n        if (status.value === 'cancelled' || isAbortError(reason) || disposed) return\n        const uploadError = reason instanceof UploadError\n          ? reason\n          : new UploadError('UPLOAD_FAILED', `Vobs Upload: ${fileName(file, id)} 上传失败`, reason)\n        error.value = uploadError\n        status.value = 'error'\n        settle?.(null)\n        settle = undefined\n      }\n    }\n\n    function updateProgress(value: HTTPProgress): void {\n      if (status.value !== 'uploading' || value.percent === undefined) return\n      progress.value = Math.max(0, Math.min(100, value.percent))\n    }\n\n    function isCancelled(): boolean {\n      return status.value === 'cancelled'\n    }\n  }\n\n  function createFormData(file: UploadFile, id: string, taskOptions: UploadTaskOptions<Result>): FormData {\n    if (typeof FormData === 'undefined') {\n      throw new UploadError('UPLOAD_UNAVAILABLE', 'Vobs Upload: 当前环境没有可用的 FormData')\n    }\n    const form = new FormData()\n    form.append(taskOptions.fieldName ?? fieldName, file, taskOptions.fileName ?? fileName(file, id))\n    const metadata = { ...(options.metadata ?? {}), ...(taskOptions.metadata ?? {}) }\n    for (const [key, value] of Object.entries(metadata)) {\n      if (value === undefined || value === null) continue\n      if (value instanceof Blob) form.append(key, value)\n      else form.append(key, String(value))\n    }\n    return form\n  }\n\n  function enqueue(run: () => void): void {\n    queue.push(run)\n    drain()\n  }\n\n  function drain(): void {\n    while (!disposed && active < concurrency && queue.length > 0) {\n      const run = queue.shift()!\n      active++\n      Promise.resolve()\n        .then(run)\n        .finally(() => {\n          active--\n          drain()\n        })\n    }\n  }\n\n  function validateFile(file: UploadFile): void {\n    if (!isUploadFile(file)) {\n      throw new UploadError('INVALID_FILE', 'Vobs Upload: file 必须是 Blob 或 File')\n    }\n    if (options.maxFileSize !== undefined && file.size > options.maxFileSize) {\n      throw new UploadError('FILE_TOO_LARGE', `Vobs Upload: 文件大小超过 ${options.maxFileSize} 字节限制`)\n    }\n    if (!matchesAccept(file, options.accept)) {\n      throw new UploadError('FILE_TYPE_UNSUPPORTED', `Vobs Upload: 不支持文件类型 ${file.type || fileName(file, 'file')}`)\n    }\n  }\n\n  function ensureActive(): void {\n    if (disposed) throw new UploadError('UPLOAD_CONTEXT_DISPOSED', 'Vobs Upload: 上下文已销毁')\n  }\n}\n\ninterface InternalUploadTask<Result> extends UploadTask<Result> {\n  __run(): Promise<void>\n  __dispose(): void\n}\n\nexport function uploadPlugin<Result = unknown>(options: UploadPluginOptions<Result>): VobsPlugin {\n  return {\n    name: '@vobs/upload',\n    version: '0.1.0',\n    install(context) {\n      const http = options.http ?? context.inject(HTTP_KEY)\n      const ownedUpload = options.upload ? undefined : createUpload({ ...options, http: requireHTTP(http) })\n      context.provide(UPLOAD_KEY, options.upload ?? ownedUpload!)\n      return () => ownedUpload?.dispose()\n    }\n  }\n}\n\nexport function useUpload<Result = unknown>(): UploadContext<Result> {\n  const upload = inject(UPLOAD_KEY)\n  if (!upload) throw new UploadError('UPLOAD_CONTEXT_MISSING', 'Vobs Upload: 找不到上下文，请安装 uploadPlugin')\n  return upload as UploadContext<Result>\n}\n\nfunction validateOptions<Result>(options: UploadOptions<Result>): void {\n  if (!options || typeof options !== 'object' || !options.http || typeof options.http.request !== 'function') {\n    throw new UploadError('INVALID_UPLOAD_OPTIONS', 'Vobs Upload: 必须提供 HTTPClient')\n  }\n  if (!options.url || typeof options.url !== 'string') {\n    throw new UploadError('INVALID_UPLOAD_OPTIONS', 'Vobs Upload: url 必须是非空字符串')\n  }\n  if (options.method !== undefined && !['POST', 'PUT', 'PATCH'].includes(options.method)) {\n    throw new UploadError('INVALID_UPLOAD_OPTIONS', 'Vobs Upload: method 只能是 POST、PUT 或 PATCH')\n  }\n  if (options.maxFileSize !== undefined && (!Number.isFinite(options.maxFileSize) || options.maxFileSize < 0)) {\n    throw new UploadError('INVALID_UPLOAD_OPTIONS', 'Vobs Upload: maxFileSize 必须是大于等于 0 的有限数字')\n  }\n  if (options.concurrency !== undefined && (!Number.isInteger(options.concurrency) || options.concurrency <= 0)) {\n    throw new UploadError('INVALID_UPLOAD_OPTIONS', 'Vobs Upload: concurrency 必须是正整数')\n  }\n}\n\nfunction requireHTTP(client: HTTPClient | undefined): HTTPClient {\n  if (client) return client\n  throw new UploadError('UPLOAD_CONTEXT_MISSING', 'Vobs Upload: 找不到 HTTPClient，请安装 httpPlugin 或传入 http')\n}\n\nfunction matchesAccept(file: UploadFile, accept: UploadOptions['accept']): boolean {\n  if (!accept || (Array.isArray(accept) && accept.length === 0)) return true\n  const name = fileName(file, '')\n  const accepted = typeof accept === 'string' ? accept.split(',') : accept\n  return accepted.map(value => value.trim().toLowerCase()).some(pattern => {\n    if (!pattern) return false\n    if (pattern.startsWith('.')) return name.toLowerCase().endsWith(pattern)\n    if (pattern.endsWith('/*')) return file.type.toLowerCase().startsWith(pattern.slice(0, -1))\n    return file.type.toLowerCase() === pattern\n  })\n}\n\nfunction isUploadFile(value: unknown): value is UploadFile {\n  return typeof Blob !== 'undefined' && value instanceof Blob\n}\n\nfunction fileName(file: UploadFile, fallback: string): string {\n  return typeof file.name === 'string' && file.name.trim() !== '' ? file.name : fallback\n}\n\nfunction isAbortError(value: unknown): boolean {\n  return Boolean(value) && typeof value === 'object' && (value as { name?: unknown }).name === 'AbortError'\n}\n"],"mappings":"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","names":["task"]}