@mountra/mountra-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +126 -0
- package/dist/index.cjs +751 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +309 -0
- package/dist/index.d.ts +309 -0
- package/dist/index.js +711 -0
- package/dist/index.js.map +1 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# @mountra/mountra-sdk
|
|
2
|
+
|
|
3
|
+
用于浏览器前端接入 Mountra 的 TypeScript SDK。当前提供统一的文件上传工具:普通 chunk 使用签名 PUT,jumbo chunk 使用 S3 Multipart。
|
|
4
|
+
|
|
5
|
+
## 使用
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { createMountraClient } from "@mountra/mountra-sdk";
|
|
9
|
+
|
|
10
|
+
const mountra = createMountraClient({
|
|
11
|
+
baseUrl: "https://mountra.example.com",
|
|
12
|
+
token: "your-bearer-token",
|
|
13
|
+
workspaceCuid: "workspace-cuid",
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const result = await mountra.upload(file, {
|
|
17
|
+
path: "/documents/report.pdf",
|
|
18
|
+
// 默认是 1:整个文件作为一个 chunk 上传
|
|
19
|
+
chunkCount: 1,
|
|
20
|
+
onProgress: ({ uploadedBytes, totalBytes }) => {
|
|
21
|
+
console.log(`${uploadedBytes}/${totalBytes}`);
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
console.log(result.ino, result.path);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
SDK 会先计算文件及每个 chunk 的 SHA-256,然后调用 `/api/upload/prepare`。对返回的每个签名 URL 按 chunk 顺序执行 PUT,最后调用 `/api/upload/finish`。
|
|
29
|
+
|
|
30
|
+
## Jumbo chunk
|
|
31
|
+
|
|
32
|
+
尺寸严格大于 128 MiB 的 chunk 会走 S3 Multipart。SDK 不直接绑定某一个 S3 SDK,而是提供 `S3MultipartUploader` 适配器,宿主应用把实际 S3 SDK 的三个操作接入即可:
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { S3MultipartUploader } from "@mountra/mountra-sdk";
|
|
36
|
+
|
|
37
|
+
const s3MultipartUploader = new S3MultipartUploader({
|
|
38
|
+
bucket: "mountra-bucket",
|
|
39
|
+
client: {
|
|
40
|
+
createMultipartUpload: async ({ bucket, key, contentType, signal }) => {
|
|
41
|
+
const result = await s3.createMultipartUpload({
|
|
42
|
+
Bucket: bucket,
|
|
43
|
+
Key: key,
|
|
44
|
+
ContentType: contentType,
|
|
45
|
+
signal,
|
|
46
|
+
});
|
|
47
|
+
return { uploadId: result.UploadId! };
|
|
48
|
+
},
|
|
49
|
+
uploadPart: async ({ bucket, key, uploadId, partNumber, body, signal }) => {
|
|
50
|
+
const result = await s3.uploadPart({
|
|
51
|
+
Bucket: bucket,
|
|
52
|
+
Key: key,
|
|
53
|
+
UploadId: uploadId,
|
|
54
|
+
PartNumber: partNumber,
|
|
55
|
+
Body: body,
|
|
56
|
+
signal,
|
|
57
|
+
});
|
|
58
|
+
return { etag: result.ETag! };
|
|
59
|
+
},
|
|
60
|
+
completeMultipartUpload: async ({ bucket, key, uploadId, parts, signal }) => {
|
|
61
|
+
await s3.completeMultipartUpload({
|
|
62
|
+
Bucket: bucket,
|
|
63
|
+
Key: key,
|
|
64
|
+
UploadId: uploadId,
|
|
65
|
+
MultipartUpload: { Parts: parts.map(({ partNumber, etag }) => ({ PartNumber: partNumber, ETag: etag })) },
|
|
66
|
+
signal,
|
|
67
|
+
});
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
默认每个 S3 part 为 16 MiB,可通过 `jumboPartSize` 调整,但不能小于 S3 要求的 5 MiB。每个成功的 part 都会写入 `localStorage` checkpoint;发生中断后,再次调用 `upload` 或 `resumeUpload` 会跳过已记录且 hash/size 匹配的 part,继续上传剩余 part。S3 Multipart 完成后,SDK 仍会调用 Mountra `/api/upload/finish`,只有两者都成功才清理本地 checkpoint。
|
|
74
|
+
|
|
75
|
+
传入的 bucket 和凭证必须能够访问 Mountra prepare 返回的 `storage_key` 对应对象存储;SDK 不会把 Mountra 服务端的存储凭证暴露到接口响应中。
|
|
76
|
+
|
|
77
|
+
`prepareUpload` 会同时返回可序列化的 `context`。客户端应把它和可恢复的文件/blob 引用一起保存到 IndexedDB 等本地存储中:
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
const prepared = await mountra.prepareUpload(file, {
|
|
81
|
+
path: "/documents/report.pdf",
|
|
82
|
+
chunkCount: 8,
|
|
83
|
+
onSessionPrepared: async (context) => {
|
|
84
|
+
await uploadStore.save(context); // 不能只保存 uploadId
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// 应用重启后恢复同一个文件/blob 和 context
|
|
89
|
+
const status = await mountra.getUploadStatus(prepared.context.uploadId);
|
|
90
|
+
const result = await mountra.resumeUpload(file, prepared.context);
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`getUploadStatus` 返回每个 chunk 的 `pending/uploaded` 状态,以及 pending chunk 可直接使用的 PUT 目标。服务端会根据对象存储中的对象重新校验状态,因此客户端不应仅依赖内存中的上传进度。
|
|
94
|
+
|
|
95
|
+
`chunkCount > 1` 时请求使用 `chunk_method: "fix"`。云端会为每个 chunk 保存独立的 descriptor,并在 status 查询中根据对象存储重新确认上传状态。
|
|
96
|
+
|
|
97
|
+
## 开发
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
pnpm --dir mountra-sdk install
|
|
101
|
+
pnpm --dir mountra-sdk typecheck
|
|
102
|
+
pnpm --dir mountra-sdk test
|
|
103
|
+
pnpm --dir mountra-sdk build
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## 发布到 NPM
|
|
107
|
+
|
|
108
|
+
先使用拥有 `@mountra` scope 发布权限的账号登录 NPM:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
npm login
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
在仓库根目录执行:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
pnpm publish:sdk
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
发布脚本会依次执行类型检查、测试和构建,然后发布公开的 `@mountra/mountra-sdk` package。实际发布前可以先预览将要发布的内容:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
pnpm publish:sdk --dry-run
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
发布包只包含 `dist/` 和本 README,不包含源码与测试文件。
|