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 🙏

© 2024 – Pkg Stats / Ryan Hefner

yuuki-uploader

v1.1.0

Published

支持TypeScript的大文件分片上传器

Downloads

1

Readme

Yuuki-Uploader

基于 HTML5 的文件上传器,内置Spark-MD5,实现了文件分片上传、分片检测、断点续传等功能。

安装


npm install yuuki-uploader

基本用法

默认导出 Uploader 类,创建 Uploader 实例即可使用

import Uploader from 'yuuki-uploader'

const uploader = new Uploader({
  target: 'http://example.com/upload',
  mergeTarget: 'http://example.com/merge'
})

将 Uploader 挂载至 DOM 元素上

const addButton = document.querySelector('#fileAdd')
const UploadButton = document.querySelector('#fileUpload')

uploader.register(addButton)
// uploader.unRegister(button)

UploadButton.addEventListener('click', () => uploader.upload())

服务端接收分片

前端在上传文件前可以在 precheck 配置项中确定是否上传该文件,每个分片上传前都会发起 get 请求,根据后端返回的状态码决定是否发起 post 请求上传该分片,在所有分片成功发送后,前端会发起 post 请求通知后端合并文件,同样根据状态码判断是否合并成功。

每个上传分片至少包含以下信息:

totalChunks: number //总块数 chunkSize: number //预设分块标准大小 filename: string //文件名 totalSize: number //总文件大小 hash: string //文件 md5 webkitRelativePath: string //上传文件夹时文件路径

  • chunkIndex: 当前块号
  • totalChunks: 总块数
  • chunkSize: 预设分块标准大小
  • currentSize: 当前块大小
  • totalSize: 总文件大小
  • filename: 文件名
  • hash: 文件 MD5 值
  • webkitRelativePath: 上传文件夹时文件路径

得到状态码后的操作:

  • 认为请求成功需要上传的状态码: 200, 201, 202

  • 认为请求成功不需要上传的状态码: 204, 205, 206

  • 认为请求失败不再进行上传的状态码: 404, 415, 500, 501

  • 其它状态码会自动重传直到重传次数上限

API 文档

Uploader

构造函数

实例化的时候可以传入配置项

const uploader = new Uploader(options)

options 配置项的数据类型

export type Options = Readonly<{
  target: string //上传目标url,默认为'/'
  mergeTarget: string //合并url,默认为'/'
  multiple: boolean //文件多选(multiple实现),默认为true
  accept: string //接受的文件类型,默认为''
  directoryMode: boolean //选择文件夹上传(multiple失效),默认为false
  replaceMode: boolean //每次选择都会替换待选文件列表,默认为false
  chunkSize: number //分块大小(byte),默认为 2 * 1024 * 1024
  concurrency: number //最大并发数量,默认为3
  headers: Record<string, string> //附带请求头,默认为{}
  progressCallbacksInterval: number //进度条回调最小间隔,默认为200
  successCodes: number[] //认为上传和合并文件成功的http状态码,默认为[200,201,202]
  skipCodes: number[] //认为get测试请求需要跳过上传的http状态码,默认为[204,205,206]
  errorCodes: number[] //认为上传和合并文件失败的http状态码,默认为[404,415,500,501]
  precheck?: (file: UploadFile) => Promise<boolean> //自定义预检方法,默认为undefined
}>

实例属性与方法

export class Uploader {
  //属性
  readonly options: Options //配置
  readonly fileList: UploadFile[] //待上传的所有文件(是UploadFile[]不是FileList类型)
  readonly uploadList: UploadFile[] //正在上传的文件队列

  //监听事件
  onDragEnter?: (event: DragEvent) => void //拖拽文件进入时调用
  onDragOver?: (event: DragEvent) => void //拖拽文件在指定区域时周期性调用
  onDragLeave?: (event: DragEvent) => void //拖拽文件离开指定区域时调用
  onFileAdded?: (file: File) => boolean | Promise<boolean> | void //每一个文件加入待传队列前调用
  onFileReady?: (file: UploadFile) => void //每一个文件添加完毕后调用
  onFileRemoved?: (file: UploadFile) => void //一个文件被移除时调用
  onFilePaused?: (file: UploadFile) => void //一个文件暂停时调用
  onFileFailed?: (file: UploadFile, error: Error) => void //一个文件错误时调用
  onFileCompleted?: (file: UploadFile) => void //一个文件的所有分块全部上传成功时调用
  onFileSuccess?: (file: UploadFile) => void //一个文件上传成功时调用(已完成合并请求)
  onFileProgress?: (file: UploadFile) => void //一个文件正在上传时反复调用

  //方法
  register(element: HTMLElement): void //将传入元素注册为uploader
  unRegister(element: HTMLElement): void //解除传入元素的uploader
  registerDrop(element: HTMLElement): void //将传入元素注册为拖拽上传的uploader
  unRegisterDrop(element: HTMLElement): void //解除传入元素为拖拽上传的uploader
  async addFile(file: File): Promise<void> //添加单个文件
  async addFileList(fileList: File[]): Promise<void> //添加文件列表
  removeFile(file: UploadFile): void //移除传入文件
  upload: (): void //开始上传待传队列的所有文件
  pause(): void  //暂停全部上传
  cancel(): void //取消全部上传
}

UploadFile

实例属性与方法

export class UploadFile {
  //属性
  readonly uploader: Uploader //对应的uploader实例
  readonly file: File //原生文件对象
  readonly hash: string //md5值
  query: Record<string, string | number> //用户自定义chunk上传参数(仅限字符串,因为是FormData)
  mergeAppend: Record<string, any> //merge合并请求中追加参数

  //方法
  async upload(): Promise<void> //上传该文件
  pause(): void //暂停上传该文件
  cancel(): void //取消上传该文件
  resume(): void //恢复上传该文件

  get progress(): number //获得文件上传进度(0-1)

  get currentSpeed(): number //获得上传瞬时速度(byte)

  get averageSpeed(): number //获得上传平均速度(byte)

  get status(): FileStatus // 获得该文件状态
}

type FileStatus = 'waiting' | 'uploading' | 'paused' | 'completed' | 'success' | 'failed'

文件状态类型 FileStatus

一个 Uploader 中的文件存在以下状态:

  • waiting: 等待上传
  • uploading: 正在上传
  • paused: 暂停中
  • completed: 所有分块上传完毕,但未合并
  • success: 所有分块上传完毕,并且合并成功
  • failed: 上传失败(无论什么原因)

作者附

可能用起来非常垃圾,实例代码也写的很垃圾,可以考虑直接 clone 源码修改一下,所有逻辑都很简单 ——来自垃圾作者