架构
ChunkFlow 采用分层架构设计,每一层都有特定的职责,并且可以独立使用。
分层架构
┌─────────────────────────────────────────────────────────────┐
│ 应用层 (Apps) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Playground │ │ Server │ │ Website │ │
│ │ (Demo) │ │ (Nest.js) │ │ (VitePress) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────────────────┐
│ 组件层 (Components) │
│ ┌──────────────────────────┐ ┌──────────────────────────┐ │
│ │ upload-component-react │ │ upload-component-vue │ │
│ └──────────────────────────┘ └──────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────────────────┐
│ 框架适配层 (Client) │
│ ┌──────────────────────────┐ ┌──────────────────────────┐ │
│ │ upload-client-react │ │ upload-client-vue │ │
│ └──────────────────────────┘ └──────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────────────────┐
│ 核心层 (Core) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ @chunkflowjs/core │ │
│ │ - UploadManager (状态机、队列管理) │ │
│ │ - UploadTask (单个上传任务) │ │
│ │ - Plugin System (插件机制) │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────────────────┐
│ 共享层 (Shared) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ @chunkflowjs/shared │ │
│ │ - 事件系统 (mitt) │ │
│ │ - 并发控制 (p-limit) │ │
│ │ - 文件工具 (切片、Hash) │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────────────────┐
│ 协议层 (Protocol) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ @chunkflowjs/protocol │ │
│ │ - 接口定义 (TypeScript Types) │ │
│ │ - 请求/响应格式 │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 服务端层 (Server) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ @chunkflowjs/server │ │
│ │ - BFF SDK │ │
│ │ - 存储适配器 │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘层级职责
协议层 (@chunkflowjs/protocol)
目的:定义通信契约
职责:
- TypeScript 类型定义
- API 请求/响应接口
- 错误类型
- 常量
依赖:无
被使用:所有其他层
关键文件:
types.ts- 核心类型定义interfaces.ts- API 接口constants.ts- 常量
共享层 (@chunkflowjs/shared)
目的:提供通用工具
职责:
- 事件系统(使用 mitt)
- 并发控制(使用 p-limit)
- 文件工具(切片、哈希)
- IndexedDB 存储
- 辅助函数
依赖:协议层
被使用:核心层、客户端层、组件层
关键文件:
events.ts- 事件总线concurrency.ts- 并发控制器file-utils.ts- 文件操作storage.ts- IndexedDB 封装
核心层 (@chunkflowjs/core)
目的:实现上传逻辑
职责:
- 上传状态机
- 任务生命周期管理
- 队列管理
- 插件系统
- 动态分片大小
- 重试逻辑
依赖:协议层、共享层
被使用:客户端层、组件层,或直接使用
关键文件:
UploadManager.ts- 任务管理器UploadTask.ts- 单个上传任务ChunkSizeAdjuster.ts- 动态分片plugins/- 插件实现
客户端层 (React/Vue)
目的:框架集成
职责:
- 框架特定适配器
- 响应式状态管理
- 生命周期集成
- Context/Provider 设置
依赖:核心层
被使用:组件层,或直接使用
React 包:
UploadProvider.tsx- Context provideruseUpload.ts- Upload hookuseUploadList.ts- List hookuseUploadManager.ts- Manager hook
Vue 包:
plugin.ts- Vue 插件useUpload.ts- Upload composableuseUploadList.ts- List composable
组件层 (React/Vue)
目的:开箱即用的 UI 组件
职责:
- 预构建的上传组件
- 默认样式
- 无障碍访问
- 用户交互
依赖:客户端层
被使用:应用程序
组件:
UploadButton- 文件选择UploadList- 任务列表UploadProgress- 进度条UploadDropzone- 拖放区域
服务端层 (@chunkflowjs/upload-server)
目的:服务端实现
职责:
- 上传服务逻辑
- 存储适配器
- 数据库适配器
- Token 管理
- 文件流处理
依赖:协议层
被使用:服务端应用
关键文件:
UploadService.ts- 主服务adapters/storage/- 存储适配器adapters/database/- 数据库适配器
设计原则
1. 高度解耦
每一层都是独立的,可以单独使用:
typescript
// 仅使用核心层
import { UploadManager } from "@chunkflowjs/core";
// 使用核心层 + React 客户端
import { UploadManager } from "@chunkflowjs/core";
import { useUpload } from "@chunkflowjs/upload-client-react";
// 使用全部
import { UploadButton } from "@chunkflowjs/upload-component-react";2. 渐进增强
从简单开始,根据需要添加功能:
typescript
// 基础上传
const task = manager.createTask(file);
await task.start();
// 添加进度跟踪
task.on("progress", ({ progress }) => {
console.log(progress);
});
// 添加插件
manager.use(new LoggerPlugin());
manager.use(new StatisticsPlugin());3. 性能优先
内置优化:
- 并行哈希计算和上传
- 动态分片大小
- 并发控制
- 请求池化
4. 类型安全
完整的 TypeScript 支持:
- 所有 API 都有类型
- 类型推断无处不在
- 公共 API 中没有
any类型
5. 可测试性
每一层都可以独立测试:
- 工具函数的单元测试
- 层级的集成测试
- 正确性的属性测试
数据流
上传流程
用户选择文件
↓
UploadManager.createTask()
↓
创建 UploadTask
↓
task.start()
↓
┌──────────────────┬──────────────────┐
│ │ │
│ 哈希 │ 上传 │
│ 计算 │ 分片 │
│ (并行) │ (并行) │
│ │ │
└──────────────────┴──────────────────┘
↓ ↓
哈希完成 所有分片上传完成
↓ ↓
验证哈希 合并文件
↓ ↓
┌──────────────────────────────────────┐
│ 文件存在? │
│ 是 → 秒传(取消分片上传) │
│ 否 → 继续上传 │
└──────────────────────────────────────┘
↓
上传完成
↓
触发成功事件状态机
┌─────┐
│IDLE │
└──┬──┘
│ start()
↓
┌────────┐
│HASHING │
└───┬────┘
│
↓
┌──────────┐
│UPLOADING │←──────┐
└─┬──┬──┬──┘ │
│ │ │ │
│ │ └──pause() │
│ │ │
│ │ ┌──────┐ │
│ │ │PAUSED│───┘
│ │ └──────┘ resume()
│ │
│ └──cancel()
│ ┌─────────┐
│ │CANCELLED│
│ └─────────┘
│
├──success()
│ ┌───────┐
│ │SUCCESS│
│ └───────┘
│
└──error()
┌─────┐
│ERROR│
└─────┘包结构
chunkflow/
├── packages/
│ ├── protocol/ # 协议层
│ │ ├── src/
│ │ │ ├── types.ts
│ │ │ ├── interfaces.ts
│ │ │ └── constants.ts
│ │ └── package.json
│ │
│ ├── shared/ # 共享层
│ │ ├── src/
│ │ │ ├── events.ts
│ │ │ ├── concurrency.ts
│ │ │ ├── file-utils.ts
│ │ │ └── storage.ts
│ │ └── package.json
│ │
│ ├── core/ # 核心层
│ │ ├── src/
│ │ │ ├── UploadManager.ts
│ │ │ ├── UploadTask.ts
│ │ │ ├── ChunkSizeAdjuster.ts
│ │ │ └── plugins/
│ │ └── package.json
│ │
│ ├── upload-client-react/ # React 客户端
│ │ ├── src/
│ │ │ ├── UploadProvider.tsx
│ │ │ ├── useUpload.ts
│ │ │ └── useUploadList.ts
│ │ └── package.json
│ │
│ ├── upload-client-vue/ # Vue 客户端
│ │ ├── src/
│ │ │ ├── plugin.ts
│ │ │ ├── useUpload.ts
│ │ │ └── useUploadList.ts
│ │ └── package.json
│ │
│ ├── upload-component-react/# React 组件
│ │ ├── src/
│ │ │ ├── UploadButton.tsx
│ │ │ ├── UploadList.tsx
│ │ │ ├── UploadProgress.tsx
│ │ │ └── UploadDropzone.tsx
│ │ └── package.json
│ │
│ ├── upload-component-vue/ # Vue 组件
│ │ ├── src/
│ │ │ ├── UploadButton.vue
│ │ │ ├── UploadList.vue
│ │ │ ├── UploadProgress.vue
│ │ │ └── UploadDropzone.vue
│ │ └── package.json
│ │
│ └── upload-server/ # 服务端 SDK
│ ├── src/
│ │ ├── UploadService.ts
│ │ └── adapters/
│ └── package.json
│
└── apps/
├── server/ # 演示服务器
├── playground/ # 演示应用
└── website/ # 文档依赖关系图
Protocol ← Shared ← Core ← Client ← Component
↑ ↑
└─────────────────────────┘
Protocol ← Server扩展点
1. 自定义请求适配器
实现 RequestAdapter 接口以支持自定义 HTTP 客户端。
2. 自定义存储适配器
实现 StorageAdapter 接口以支持自定义存储后端。
3. 自定义数据库适配器
实现 DatabaseAdapter 接口以支持自定义数据库。
4. 插件
实现 Plugin 接口以扩展功能。
5. 自定义组件
使用客户端层的 hooks/composables 构建自定义 UI 组件。
