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

@seaart/edge-media-upload

v0.1.2

Published

SeaArt browser media upload client for the edge upload protocol

Readme

@seaart/edge-media-upload

SeaArt 浏览器端统一媒体上传核心包,支持图片、GIF、视频和音频。

上传流程:

  1. 获取 /api/upload/edge/pre-sign 预签名。
  2. 使用 vod-js-sdk-v6 上传主媒体;视频封面附件使用预签名 URL 直传。
  3. 调用 /api/upload/edge/complete 转换为站内 CDN 地址。

包本身不依赖 Vue、Nuxt、Element 或具体请求库。登录态、请求 Header、UI 提示和埋点由业务项目通过请求配置与 hooks 注入。

使用

import { createMediaUploadClient } from '@seaart/edge-media-upload';

const client = createMediaUploadClient({
  baseURL: 'https://api.example.com',
  getHeaders: () => ({ Authorization: getAuthorization() }),
});

const result = await client.upload(file, { category: 2 });

需要进度或取消能力时:

const uploader = client.createUploader({
  file,
  category: 8,
  onProgress: (_event, progress) => updateProgress(progress),
});

const result = await uploader.beforeUpload();
uploader.cancel();

客户端参数

createMediaUploadClient(config) 的配置如下:

| 参数 | 类型 | 必填 | 默认值 | 说明 | | ---------------- | ----------------------------------------------------------------- | ---- | ---------------------- | ---------------------------------------------------- | | baseURL | string | 否 | '' | API 基础地址。空字符串表示使用当前站点的 /api 代理 | | getHeaders | () => Record<string, string> \| Promise<Record<string, string>> | 否 | - | 每次业务请求前获取登录态、游客标识、语言等 Header | | request | (options: UploadRequestOptions) => Promise<unknown> | 否 | 内置 fetch | 自定义业务请求方法,适配 Web/H5 的统一请求封装 | | hooks | UploadHooks | 否 | - | 上传结果、通用错误和 SDK 错误回调 | | bucket | string | 否 | 'image' | 预签名参数中的存储 bucket | | preprocessFile | (file) => file \| Promise<file> | 否 | - | 文件上传前预处理,例如图片转 WebP | | loadVodSdk | () => Promise<VodClientConstructor> | 否 | 懒加载 vod-js-sdk-v6 | 自定义 SDK 加载器,主要用于测试或特殊运行环境 |

baseURLgetHeadersrequest 是请求相关配置。未传 request 时,公共包使用内置 fetch,并固定设置 credentials: 'include'

上传参数

client.upload(file, options)client.createUploader(options) 使用以下参数:

| 参数 | 类型 | 必填 | 默认值 | 说明 | | ---------------------------------------- | --------------------------------------- | ---- | --------------------------- | -------------------------------------------------------------------------------------------- | | file | File \| Blob | 是 | - | 主媒体文件。client.upload() 通过第一个参数传入,实例模式可在创建或 beforeUpload() 时传入 | | category | string \| number | 是 | - | 资源业务分类。上传前会校验,并保留在上传生命周期上下文中 | | name | string | 否 | 文件原名 | 高阶上传入口中的文件名别名 | | mediaName | string | 否 | 文件原名 | 传给 VOD SDK 的媒体名称,并作为缺失文件名时的兜底 | | templateId / template_id | string \| number | 否 | - | 应用模板 ID,保留用于兼容现有调用方 | | maxSize | number | 否 | 图片/视频 1 GB,音频 100 MB | 文件大小上限,单位为字节 | | chunkSize | number | 否 | 预签名返回值或 SDK 默认值 | VOD SDK 主媒体分片大小,单位为字节,必须为正整数 | | preprocess | boolean | 否 | true | 是否执行客户端 preprocessFile,仅作用于 client.upload() | | onProgress | (event, progress) => void | 否 | - | 主媒体上传进度回调,progress 范围为 0-100 | | trackResult | boolean | 否 | true | 设为 false 时不触发 hooks.onResult,用于避免兼容层重复上报 | | uploadTrack | unknown | 否 | - | 业务埋点上下文,保留在 Hook 的 event.params 中,不传给 SDK | | other.templateId / other.template_id | string \| number | 否 | - | client.upload() 对模板 ID 的兼容取值 | | getSignature | (params) => string \| Promise<string> | 否 | - | 高级覆盖项,直接提供 VOD 签名并跳过默认 pre-sign 请求,参见下方注意事项 | | 其他字段 | unknown | 否 | - | 未被公共包消费的字段会透传给 VOD SDK 的 upload() 参数 |

当前不支持调用方传入视频封面。上传视频时,公共包会尝试截取视频首帧并生成临时 WebP 封面,再通过 pre-sign 返回的 attachments[].pre_signs[] 单独 PUT 上传。

chunkSize 的取值优先级为:调用方参数 > pre-sign.data.chunk_size > VOD SDK 默认值。传入 chunkSize 后只覆盖主媒体的 SDK 分片大小,不改变自动生成封面附件的服务端分片规则。

预签名参数

公共包根据文件自动生成:

{
  name: file.name,
  size: file.size,
  bucket: 'image',
  hash: md5(file.name),
  attachments: generatedCoverFiles.map(/* 同样的 name/size/bucket/hash */),
}

其中 attachments 仅在存在视频封面时携带。

使用 getSignature 会跳过默认 pre-sign,公共包因而无法获得 uploadId 和封面 attachments。仅应在自定义后端链路不依赖这些字段时使用,普通业务上传不要配置。

实例方法与状态

client.createUploader(options) 返回 MediaUploader

| 方法 | 说明 | | ------------------------------- | ---------------------------------------------------- | | beforeUpload(file?, options?) | 开始上传,保留旧版调用名称 | | upload(file?, options?) | beforeUpload() 的别名 | | cancel() | 取消 SDK、附件和业务接口请求,并使旧任务异步回调失效 | | applyOptions(options) | 更新实例参数 | | resetStatus() | 将进度和结果重置为初始状态 |

可读取的主要状态:

| 字段 | 说明 | | ----------------- | ------------------------------------------------------- | | uploading | 当前是否正在上传 | | uploadingStatus | initpendingcompleteerrorcancelled | | progress | 主媒体上传进度,范围为 0-100 | | result | 当前上传结果 | | uploadId | pre-sign 返回的任务 ID | | preSigns | 主媒体预签名列表 | | chunkSize | 当前任务实际使用的分片大小;未指定且后端未返回时为 0 | | exceptChunkNum | 后端返回的期望分片并发数,对应 SDK chunkParallelLimit |

返回值

上传成功返回 UploadResult

| 字段 | 类型 | 说明 | | --------------------------- | --------------------- | -------------------------------------------------- | | url | string | complete 返回的最终资源地址 | | info | VodUploadResult | SDK 原始结果,媒体 URL 已替换为最终资源地址 | | fileId | string | VOD SDK 返回的文件 ID;SDK 未返回时为空字符串 | | image / video / audio | object \| undefined | 对应媒体类型的 SDK 结果 | | lowPath | string | complete.low_path,低清 WebP 地址 | | coverUrl | string | complete.cover_url,高清 WebP/视频封面地址 | | uploadId | string | 预签名上传任务 ID | | preSigns | PreSignItem[] | 主媒体预签名列表 | | exceptChunkNum | number | 实际使用的 SDK 分片并发参数 |

Hooks

const client = createMediaUploadClient({
  hooks: {
    onResult(event) {},
    onError(error, context) {},
    onSdkError(error, context) {},
  },
});

| Hook | 触发时机 | | ------------ | --------------------------------------------------------------- | | onResult | 上传最终成功或失败时触发;event.statussuccessfail | | onError | 当前有效任务发生错误时触发 | | onSdkError | VOD SDK 已开始但尚未完成时发生错误 |

Hooks 中抛出的异常不会改变上传结果。公共包自身的校验和协议异常使用 EdgeMediaUploadError,包含可选的 coderequestIdstage;自定义 request 或 VOD SDK 抛出的原始异常会原样向上传调用方抛出。

请求配置

请求相关配置只有三个:

  • baseURL:可选,默认空字符串,使用当前站点的 /api 代理。
  • getHeaders:可选,支持同步或异步返回登录态、游客标识、语言等 Header,用于 pre-signcomplete
  • request:可选,自定义请求实现;未传时使用内置 fetch,并固定设置 credentials: 'include'

自定义 request 示例:

const client = createMediaUploadClient({
  baseURL: '',
  getHeaders: () => ({ 'X-Device-Id': getDeviceId() }),
  request: ({ url, method, data, headers, signal }) =>
    request({
      url,
      method,
      data,
      headers,
      signal,
      customConfig: { needRemovePending: false },
    }),
});

request 可以返回完整业务响应 { data, status },也可以直接返回 data。完整响应的成功状态码必须为 10000

默认上传流程只调用预签名和完成确认两个接口,不再调用 fast-confirm。自定义 request 必须透传 signal,并关闭相同上传请求的去重取消。

request 接收的参数:

| 参数 | 类型 | 说明 | | --------- | ------------------------ | ------------------------------------------------------ | | url | string | 已拼接 baseURL 的最终接口地址 | | method | 'POST' | 当前三个业务接口均为 POST | | data | unknown | 接口请求体 | | headers | Record<string, string> | pre-signcomplete 为默认 Content-TypegetHeaders() 返回值的合并结果;fast-confirm 仅发送 Content-Type | | signal | AbortSignal | 当前上传任务的取消信号,必须透传到底层请求 |

接口响应

三个业务接口均使用统一响应外层:

{
  data: T | null,
  status: {
    code: number | string,
    msg?: string,
    request_id?: string,
  },
}

status.code10000 时视为成功,否则抛出 EdgeMediaUploadError

pre-sign

{
  data: {
    id: 'edge_xxx',
    pre_signs: [{ url: '<vod-signature>', size: 33522 }],
    status: 1,
    chunk_size: 33522,
    except_chunk_num: 1,
    attachments: [], // 仅视频封面存在时返回
  },
  status: { code: 10000, msg: 'success', request_id: 'xxx' },
}

| 字段 | 说明 | | ------------------ | ------------------------------------------------------ | | id | Edge 上传任务 ID,后续传给 complete | | pre_signs | 主媒体签名列表;当前使用第一项 url 作为 VOD SDK 签名 | | chunk_size | SDK 分片大小,对应 chunkSize | | except_chunk_num | SDK 分片并发数,对应 chunkParallelLimit | | attachments | 视频封面附件的路径及 PUT 预签名列表 |

complete

{
  data: {
    path: 'upload/static/20260723/example.webp',
    low_path: 'https://image.seaartcdn.com/upload/static/20260723/example.webp?eo-img.resize=w/474&eo-img.format=webp',
    url: 'https://image.seaartcdn.com/upload/static/20260723/example.webp',
    cover_url: 'https://image.seaartcdn.com/upload/static/20260723/example.webp',
  },
  status: { code: 10000, msg: 'success', request_id: 'xxx' },
}

| 字段 | 说明 | | ----------- | ----------------------------------------------------- | | path | CDN 内部相对路径 | | url | 最终资源地址,也是 UploadResult.url 的来源 | | low_path | 低清 WebP 地址,传给 fast-confirm.low_webp | | cover_url | 高清 WebP/视频封面地址,传给 fast-confirm.high_webp |

fast-confirm

{
  data: {
    file_id: '',
    url: 'https://image.seaartcdn.com/upload/static/20260723/example.webp',
    video_info: null,
  },
  status: { code: 10000, msg: 'success', request_id: 'xxx' },
}

| 字段 | 说明 | | ------------ | --------------------------------------------------------------------- | | file_id | 风控确认后的文件 ID;为空时 UploadResult.fileId 回退到 SDK fileId | | url | 鉴定通过后原样返回的资源地址 | | video_info | 视频附加信息;非视频或后端未生成时可能为 null |

浏览器与 SSR

包可以在 SSR 构建阶段安全导入,但上传只能在浏览器环境执行。腾讯云 VOD SDK 会在上传开始后懒加载。