npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@sv-kit/uploader-pro

v1.0.0

Published

Chunked/resumable uploads with hash-based instant upload and adapters (HTTP multipart & S3/R2 presigned).

Readme

@sv-kit/uploader-pro

分片 / 断点续传 / 秒传(Merkle Hash)/ 并发与重试;可直传任意云,通过“适配器(adapter)”切换后端协议。 自带两套适配器:HTTP 分片(自有后端)S3 兼容多段(S3/R2/Spaces/MinIO/Ceph …)。 想上其他云(OSS/COS/GCS/七牛/又拍/TUS)?写 50~100 行适配器就能接。🧱🚀


✨ 特性

  • 分片上传(默认 5 MiB,可配置)· 并发上传 · 指数退避重试 · 可暂停/恢复/取消
  • “秒传” + 断点续传:Merkle 式文件指纹(分片 hash → 汇总 hash)+ 本地 manifest + 服务端校验
  • 适配器可插拔:协议/云供应商解耦,业务不动、一键切换
  • 事件回调:onProgress / onState / onChunk,好做 UI
  • 纯 TS,无重依赖;Svelte/SvelteKit 里用更顺,但不是 Svelte 专用
  • 全局取消:基于 AbortSignaltask.cancel() 会立刻中断所有进行中的分片请求(不再重试),并调用适配器的 abort()(若实现)

📦 安装

pnpm add @sv-kit/uploader-pro
# or: npm i / yarn add

🚀 快速开始(任选适配器)

import {
  UploadTask,
  HttpMultipartAdapter,
  S3MultipartAdapter
} from "@sv-kit/uploader-pro";

// 方案 A:自有后端分片(最通用、最可控)
const http = new HttpMultipartAdapter({ baseURL: "/api" });

// 方案 B:S3 兼容直传(S3、R2、Spaces、MinIO、Ceph…)
const s3 = new S3MultipartAdapter({ baseURL: "/api", acl: "public-read" });

const task = new UploadTask(file, {
  chunkSize: 5 * 1024 * 1024,
  concurrency: 4,
  retry: { attempts: 3, baseDelayMs: 600, jitter: true },
  adapter: http // 或 s3 / 其他云适配器
}, {
  onProgress: p => console.log(p.percent + "%"),
  onState: s => console.log("state:", s),
  onChunk: c => console.log("chunk", c.index, "ok?", c.ok)
});

await task.start({ bizId: "example-42" });
// task.pause(); task.resume(); task.cancel();

⛔️ 取消上传(AbortSignal)

本库内置全局取消:task.cancel() 会触发 AbortController.abort(),让所有正在进行的分片请求立刻停止,并将状态切到 "canceled"。如果适配器实现了 abort(sessionId),也会被调用以释放后端会话资源。

const task = new UploadTask(file, {
  chunkSize: 5 * 1024 * 1024,
  concurrency: 4,
  retry: { attempts: 3, baseDelayMs: 600, jitter: true },
  adapter: http // 或 s3 / 自定义适配器
}, { onState: s => console.log(s) });

// …用户点“取消”:
task.cancel(); // 中断所有 in-flight 分片请求,停止后续调度

自定义适配器如何接入取消?

只需要把 ctx.signal 透传给你的 fetch 即可:

// 适配器中的分片上传实现
async uploadChunk(ctx) {
  const res = await fetch(ctx.uploadUrl, {
    method: 'PUT',
    body: ctx.body,
    signal: ctx.signal, // ← 关键:支持 AbortSignal
  });
  return { ok: res.ok, etag: res.headers.get('ETag') ?? undefined };
}

说明

  • 取消后不会进入 finalize;如需清理后端临时分片,请在适配器实现 abort(sessionId) 并在服务端删除会话。
  • 如果你用 XMLHttpRequest 实现直传,需自行处理中止;推荐使用 fetch + signal 以获得一致体验。

🔌 适配器总览(多云友好)

| 适配器 | 适用场景 | 后端职责 | 前端行为 | |---|---|---|---| | HttpMultipartAdapter | 自有后端存临时分片再合并;任意云最终落盘 | prepare 返回 sessionId + 已有分片;接收 PUT /upload/:sid/:indexcomplete 合并 | 前端并发 PUT 分片到你后端 | | S3MultipartAdapter | S3 及兼容 S3 协议的对象存储(Cloudflare R2、DigitalOcean Spaces、MinIO、Ceph…) | create 返回 uploadId/key 与每片 预签名 URLcomplete 合并 | 前端直接 PUT 到对象存储(收集 ETag) | | 自定义适配器 | 阿里 OSS / 腾讯 COS / GCS / 七牛 / 又拍 / TUS 等 | 由你后端按该云的 API 签名/创建会话/合并 | 实现 prepare/uploadChunk/finalize 三步即可 |

为什么 README 里示例 S3? 因为 S3 Multipart 是事实标准,大量云兼容 S3 协议。但本包并不绑定 S3——换适配器就能换云。


🧩 接口一眼懂(写你自己的适配器)

interface UploadAdapter {
  name: string;
  prepare(ctx): Promise<{ sessionId: string; alreadyUploaded?: number[]; uploadUrls?: Record<number,string> }>;
  uploadChunk(ctx): Promise<{ ok: boolean; etag?: string }>;
  finalize(ctx): Promise<{ ok: boolean; url?: string }>;
  abort?(sessionId: string): Promise<void>;
}

约定俗成:

  • prepare:返回上传会话 sessionId,可选返回已上传分片(续传/秒传)与每片直传 URL
  • uploadChunk:上传分片(成功可回 etag 供合并用)
  • finalize:服务端合并或调用云端 Complete API
  • abort:可选,取消会话释放资源

☁️ 各云怎么用(除了 S3)

1) 阿里云 OSS / 腾讯云 COS

  • 两者都提供各自的 Multipart API,也在不少场景提供 S3 兼容端点
  • 优先选 S3 兼容端点 → 直接用 S3MultipartAdapter
  • 若需原生 API:写 OssAdapter / CosAdapter
    • prepare:后端调用云端“初始化分片上传”,为每个 partNumber 生成 预签名 URL 返回
    • uploadChunk:前端 PUT 分片到对应 URL(注意某些云要求 Content-MD5x-oss-* / x-cos-* 头)
    • finalize:后端用 UploadId + Parts(ETag) 触发合并,返回最终 URL

迁移成本:更换适配器即可;业务代码与 UI 零修改。

2) Google Cloud Storage(GCS)

  • 推荐走 Resumable Upload(单会话、多次 PUT,用 Content-Range 标定偏移)。
  • GcsResumableAdapter
    • prepare:后端向 GCS 发起 Resumable 会话,返回 sessionUrl(你可直接当 sessionId
    • uploadChunk:前端对 sessionUrl 发送 PUT,带 Content-Range: bytes start-end/total,分片体在 body
    • finalize:最后一片 PUT 成功即完成;或让后端确认并回 URL

3) 七牛 / 又拍 / 其它对象存储

  • 它们均有分片/断点续传 API(有的也提供 S3 兼容层)。
  • 套路与 OSS/COS 相同:后端生成短时可用的上传 URL(或会话),前端按片 PUT,收集标识(ETag/ctx),合并完成。

4) 通用协议:TUS

  • 若你想和跨语言/跨云的现成服务对接(tusdS3-tus-bridge 等),写 TusAdapter
    • preparePOST 创建上传;服务端回 Location 为会话 URL
    • uploadChunk:使用 PATCH,带 Upload-Offset 与分片 body
    • finalize:Tus 完成由服务端把关,前端可空实现

🧪 参考后端端点(示例)

A) HTTP 分片(最通用,自有后端落盘再合并)

  • POST /upload/prepare{ sessionId, alreadyUploaded?: number[] }
  • PUT /upload/:sessionId/:index → 写入第 index 片(返回可带 ETag
  • POST /upload/:sessionId/complete → 合并,返回 { ok, url? }
  • POST /upload/:sessionId/abort(可选)

B) S3 兼容直传

  • POST /s3/create{ sessionId, uploadUrls: Record<index,string> }
  • (前端)逐片 PUT uploadUrls[index],收集 ETag
  • POST /s3/complete → 传 { sessionId, parts: [{partNumber, etag}] },返回 { ok, url? }

这些端点只是示意;你也可以把 prepare/complete 合并到一个 GraphQL mutation、或走 Cloudflare Worker、或任何后端框架。


🧯 CORS / 安全 / 配置清单

  • CORS:直传对象存储必须在存储端配置允许:OriginPUT/POST/OPTIONS 方法、Content-Type + 需要的自定义头(如 x-oss-*/x-cos-*)。
  • 签名只在后端做:前端只拿时效性强的 URL/会话。
  • 分片大小:S3 兼容通常要求除最后一片外 ≥ 5 MiB;其他云按文档设置。建议默认 5–16 MiB。
  • 断点续传:前端 manifest + 后端 alreadyUploaded 双保险;更换设备也能靠 prepare 返回的已上传列表续传。
  • 哈希计算:超大文件建议放 WebWorker,避免阻塞 UI 线程。

🧭 我该选哪条路?

  • 你全控后端、想要最大自由度 → HttpMultipartAdapter
  • 你就想直传对象存储,而且是 S3 兼容家族 → S3MultipartAdapter
  • 你正在用 GCS/七牛/又拍 → 写一个 小适配器prepare/uploadChunk/finalize 三步照抄模板),十来分钟能跑
  • 跨云/跨端生态 → 考虑 TUS 协议,接上 TusAdapter

🗺️ Roadmap(欢迎 PR)

  • WebWorker 内计算哈希(避免主线程卡顿)
  • 多文件批量队列管理器(限速/优先级/并行度动态调整)
  • 自适应并发(根据 RTT/吞吐自动调度)
  • 现成适配器:OssAdapter / CosAdapter / GcsResumableAdapter / TusAdapter

📄 许可

MIT