@mountra/mountra-sdk 0.2.0 → 0.3.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/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.0 - 2026-10-07
4
+
5
+ ### Added
6
+
7
+ - Added an opt-in IndexedDB download cache through the `downloadCache` client option:
8
+ - Entries are isolated per workspace and stored per chunk, so unchanged chunks of a modified file are reused.
9
+ - The cache is bounded by `maxBytes` and evicts least recently used chunks.
10
+ - A file served within `ttlMs` needs no request to Mountra.
11
+ - Added the per-download `cache` option (`default`, `no-cache`, `no-store`), `getDownloadCacheUsage()`, `clearDownloadCache()`, `IndexedDBDownloadCacheStore`, and `InMemoryDownloadCacheStore`.
12
+
13
+ ### Changed
14
+
15
+ - `DownloadResult.export` is now optional: it is absent when the file was served entirely from the download cache. The new `DownloadResult.cachedBytes` reports bytes read from the cache.
16
+ - With the download cache enabled, multi-chunk files are downloaded chunk by chunk even without File System Access.
17
+ - Files uploaded through the client are cached by default, so downloading them needs no network until `ttlMs` passes. With `cache: "no-store"` on the upload, or when a chunk cannot be cached, the upload only invalidates the file's previous cache entry.
18
+
19
+ ### Fixed
20
+
21
+ - `exportFile`, `downloadFile`, and `downloadExport` now send the client's workspace when the call names none; Mountra previously rejected these requests.
22
+ - `splitFileIntoChunks` and `uploadFile({ chunkCount })` no longer produce empty or negative-sized trailing chunks when `chunkCount` does not divide the file size. `chunkCount` is now the maximum number of fixed-size chunks, so such uploads are no longer rejected by the server.
23
+
3
24
  ## 0.2.0 - 2026-08-19
4
25
 
5
26
  ### Added
package/README.md CHANGED
@@ -92,7 +92,7 @@ const result = await mountra.resumeUpload(file, prepared.context);
92
92
 
93
93
  `getUploadStatus` 返回每个 chunk 的 `pending/uploaded` 状态,以及 pending chunk 可直接使用的 PUT 目标。服务端会根据对象存储中的对象重新校验状态,因此客户端不应仅依赖内存中的上传进度。
94
94
 
95
- `chunkCount > 1` 时请求使用 `chunk_method: "fix"`。云端会为每个 chunk 保存独立的 descriptor,并在 status 查询中根据对象存储重新确认上传状态。
95
+ `chunkCount > 1` 时请求使用 `chunk_method: "fix"`:每个 chunk 为 `ceil(size / chunkCount)` 字节,只有最后一个 chunk 可以更小,因此无法整除时实际 chunk 数可能少于 `chunkCount`。未配置 `external_url` 的 Mountra 部署在导出时会用 S3 Multipart 合并 chunk,此时除最后一个外每个 chunk 都需要至少 5 MiB。云端会为每个 chunk 保存独立的 descriptor,并在 status 查询中根据对象存储重新确认上传状态。
96
96
 
97
97
  ## 下载
98
98
 
@@ -153,6 +153,59 @@ if (pending[0]) {
153
153
 
154
154
  可以通过 `downloadCheckpointStore` 注入自己的 `DownloadCheckpointStore`(测试时可使用 `InMemoryDownloadCheckpointStore`)。SDK 不会把短期签名 URL 写入 checkpoint;恢复时会重新请求 export URL。
155
155
 
156
+ ## 下载缓存
157
+
158
+ 创建客户端时传入 `downloadCache` 即可启用基于 IndexedDB 的本地下载缓存(默认关闭,传 `{}` 使用默认值):
159
+
160
+ ```ts
161
+ const mountra = createMountraClient({
162
+ baseUrl: "https://mountra.example.com",
163
+ token: "your-bearer-token",
164
+ workspaceCuid: "workspace-cuid",
165
+ downloadCache: {
166
+ maxBytes: 1024 * 1024 * 1024, // 缓存上限,默认 512 MiB;超出后按 LRU 淘汰
167
+ ttlMs: 10 * 60 * 1000, // 文件的有效期,默认 5 分钟;0 表示每次都向 Mountra 确认
168
+ },
169
+ });
170
+ ```
171
+
172
+ 下载时 SDK 先检查缓存:
173
+
174
+ - 文件未过期且所有 chunk 都在缓存中:直接从 IndexedDB 读取,不访问 Mountra,`result.export` 为空。
175
+ - 未命中或已过期:调用 `/api/file/export` 获取最新的 chunk 布局。已缓存的 chunk 从本地读取,其余 chunk 下载后写入缓存,文件重新开始计算有效期。
176
+
177
+ `result.cachedBytes` 是从缓存读取的字节数。
178
+
179
+ 缓存以 chunk 为单位,按 chunk 的 `storage_key` 索引。启用缓存后,多 chunk 文件即使没有 File System Access 也会逐个 chunk 下载,文件修改后未变化的 chunk 仍可复用。只有内容寻址的 chunk(`.../blobs/sha256/<hash>`)会被缓存,local-first 文件等内容可能变化的对象不会缓存。大于 `maxChunkBytes`(默认 128 MiB)的 chunk 不缓存,因为写入缓存前要在内存中暂存整个 chunk。
180
+
181
+ 所有条目都以 `baseUrl` 和 workspace 作为命名空间,与服务端一致,`workspaceCuid` 优先于 `workspaceId`。一个 workspace 的缓存不会被另一个 workspace 读到。`maxBytes` 是所有 workspace 共享的总上限。
182
+
183
+ 通过客户端 `upload` 的文件默认也会写入缓存:上传完成后,各 chunk 直接从本地文件写入 IndexedDB,并按路径和 inode 记录文件布局,之后在有效期内下载这个文件不需要访问网络。缓存规则与下载相同(只缓存内容寻址的 chunk,并受 `maxChunkBytes` 限制)。如果有 chunk 无法缓存,或者上传时传入 `cache: "no-store"`,就只让该文件原有的缓存失效。
184
+
185
+ 有效期内其他客户端对文件的修改不会被感知。单次下载可以用 `cache` 选项调整行为:
186
+
187
+ ```ts
188
+ await file.download({ cache: "no-cache" }); // 先向 Mountra 确认,但仍复用已缓存的 chunk
189
+ await file.download({ cache: "no-store" }); // 不读也不写缓存
190
+ await mountra.upload(blob, { path: "/backup.tar", cache: "no-store" }); // 上传后不写入缓存
191
+
192
+ await mountra.getDownloadCacheUsage(); // { bytes, chunks }
193
+ await mountra.clearDownloadCache({ workspaceCuid: "workspace-cuid" }); // 清除一个 workspace
194
+ await mountra.clearDownloadCache(); // 清除全部
195
+ ```
196
+
197
+ 缓存位于浏览器的 IndexedDB 中,同一浏览器配置文件下的页面都能读取。用户退出登录时应调用 `clearDownloadCache()`;多个用户共用浏览器时,可以为每个用户使用独立的数据库:
198
+
199
+ ```ts
200
+ import { IndexedDBDownloadCacheStore } from "@mountra/mountra-sdk";
201
+
202
+ const downloadCache = {
203
+ store: new IndexedDBDownloadCacheStore({ databaseName: `mountra-download-cache-${userId}` }),
204
+ };
205
+ ```
206
+
207
+ IndexedDB 不可用时(例如非浏览器环境)SDK 回退到内存缓存;缓存读写失败只会当作未命中,不会导致下载失败。
208
+
156
209
  ## 开发
157
210
 
158
211
  ```bash
@@ -164,23 +217,16 @@ pnpm --dir mountra-sdk build
164
217
 
165
218
  ## 发布到 NPM
166
219
 
167
- 先使用拥有 `@mountra` scope 发布权限的账号登录 NPM:
168
-
169
- ```bash
170
- npm login
171
- ```
220
+ SDK 由 GitLab CI 发布:在 `main` 上提交新的 `version` 和对应的 `## X.Y.Z - YYYY-MM-DD` CHANGELOG 段落后,推送 `sdk-vX.Y.Z` Tag,`publish:mountra-sdk` 任务会用 `npm stage publish` 把这个版本暂存到 npm,再由 maintainer 通过 2FA 批准上线。完整流程和一次性的 CI 配置见 [docs/release.md](../docs/release.md#mountra-sdk)。
172
221
 
173
- 在仓库根目录执行:
222
+ 发布脚本也可以在本地运行。先使用拥有 `@mountra` scope 发布权限的账号登录 NPM(或设置 `NPM_TOKEN`),然后在仓库根目录执行:
174
223
 
175
224
  ```bash
225
+ npm login
226
+ pnpm publish:sdk --dry-run # 预览将要发布的内容
176
227
  pnpm publish:sdk
177
228
  ```
178
229
 
179
- 发布脚本会依次执行类型检查、测试和构建,然后发布公开的 `@mountra/mountra-sdk` package。实际发布前可以先预览将要发布的内容:
180
-
181
- ```bash
182
- pnpm publish:sdk --dry-run
183
- ```
230
+ 脚本会先检查 CHANGELOG 中有当前版本的段落、`mountra-sdk` 没有未提交的改动,再依次执行类型检查、测试和构建,最后发布。版本已经在 registry 上时直接退出,不会重复发布;带预发布后缀的版本(如 `0.4.0-beta.1`)发布到 `next` dist-tag,可用 `NPM_DIST_TAG` 覆盖。
184
231
 
185
- 发布脚本默认使用 `https://registry.npmjs.org/`,如需发布到其他 registry,设置
186
- `NPM_REGISTRY` 环境变量。发布包包含 `dist/`、README 和 CHANGELOG,不包含源码与测试文件。
232
+ 加上 `--stage`(如 `pnpm publish:sdk --stage`)时改用 `npm stage publish`,需要 npm 11.15.0 及以上。默认使用 `https://registry.npmjs.org/`,如需发布到其他 registry,设置 `NPM_REGISTRY` 环境变量。发布包包含 `dist/`、README 和 CHANGELOG,不包含源码与测试文件。