> For the complete documentation index, see [llms.txt](https://summerain-1.gitbook.io/summerain/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://summerain-1.gitbook.io/summerain/zh-cn/fa-bu-shuo-ming/v2.0.2.md).

# V2.0.2

> 开发预发布版本。此版本从 `dev` 分支发布，后续修改可能较为频繁， 并且不会被默认的 `latest` 镜像选中。

## 概述

v2.0.2 让浏览器上传任务能够在刷新页面、离开页面、关闭标签页以及短暂网络故障后恢复。 客户端会在网络副作用开始前，将源文件和 V2 处理结果保存到按用户隔离的 IndexedDB 队列；再次打开上传页面时，会把本地持久化任务与服务器上传会话状态进行核对。

此版本不包含数据库迁移，也没有修改服务器上传协议。

## 变更

### 可恢复的浏览器队列

* 新增以用户和队列 ID 为联合标识的 IndexedDB 队列，共同保存源文件、SHA-256 源文件指纹、处理配方、尝试次数、可见性、上传会话标识和重试状态。
* 尽力申请浏览器持久存储，并在写入前检查可用配额，同时至少保留 32 MiB 或总配额的百分之十。
* 持久存储不可用时，将任务明确标记为“仅当前标签页”，而不是阻止全部上传。
* 设置 24 小时保留边界并进行惰性过期清理；已完成或由用户明确移除的任务会尽快删除。
* 服务器进入处理阶段后，会删除已持久化的处理后衍生文件；源文件只保留到完成、 明确移除或过期为止。

### V2 上传的崩溃恢复

* 在第一次分片 PUT 之前，先可靠保存上传会话 ID 和过期时间。
* 配方未变化时，中断后可以复用已保存的 WebP 分片，无需再次解码和编码源文件。
* 页面刷新、导航、关闭标签页和认证边界只会中止本地工作，不会隐式取消可恢复的服务器会话。
* 只有用户明确移除任务时，客户端才会请求取消服务器会话。
* 幂等键仍由队列 ID 和权威尝试次数生成，避免中断的尝试重复发布图片。

### 服务器状态核对

* 通过批量上传状态接口核对活动任务；混合批次返回 4043 时，会递归拆分并定位缺失 ID。
* 已发布任务会在本地完成，未过期的分片上传会继续，服务器处理中任务会继续轮询； 只有旧会话缺失或过期时才创建新的幂等尝试。
* 状态接口暂时不可用时只暂停队列，不进行破坏性状态修改。
* 中断的旧版 V1 请求会标记为结果未知且不可重试，并提示用户先到“我的图片”中核对。

### 多标签页与账号隔离

* 新增可续期的单次运行租约和事务级所有权检查，确保同一时间只有一个标签页能修改持久任务。
* 手动重试会从存储中的权威尝试次数和上传 ID 原子准备，阻止租约移交后的旧界面状态覆盖新状态。
* 认证代次保护会阻止过期的登录或资料请求恢复旧账号；登录、退出、修改密码以及远端认证事件 会清理当前用户边界之外的队列数据。
* 为保存中、已暂停、可恢复、仅当前标签页、存储错误和 V1 结果未知状态补充英语、 简体中文和日语界面文本。

### 依赖

* 新增精确版本运行时依赖 `idb` 8.0.3。
* 新增精确版本测试依赖 `fake-indexeddb` 6.2.5。

## 兼容性与资源行为

* 队列使用 IndexedDB、Web Crypto SHA-256、Blob 和 File API，兼容 V2 浏览器矩阵， 包括 Chromium 93 及以上版本和已部署的 iOS WebKit 605 系列。
* 浏览器图片处理仍保持串行；队列同时调度两个任务，单个标签页最多保留四个活动上传会话， 为恢复任务或其他标签页留出服务器会话容量。
* 服务端图片处理、存储布局、配方 `2.0.0` 和固定 WebP 变体均未改变。

## 验证

* 前端 Vitest：17 个测试文件，共 131 项测试通过。
* ESLint：通过。
* TypeScript 项目与 Vite 生产构建：通过。
* Python requirements 锁定文件验证：通过。
* GitBook 文档和翻译源哈希验证：通过。
* 现有 wasm-vips 依赖的 direct-eval 警告保持不变，不会导致构建失败。

## 安装

开发镜像必须显式拉取：

```bash
docker pull jaykserks/summerain:dev-v2.0.2
```

等效的精确开发标签：

```
jaykserks/summerain:dev-2.0.2
```

滚动更新的 `dev` 标签也会指向最新一次成功的开发构建。 此版本不会修改 `latest`、`main` 以及稳定的语义化版本别名。

## 已知限制

* 浏览器未授予持久存储权限时仍可能回收队列数据；首次持久写入失败的任务会标记为仅当前标签页。
* 24 小时清理是惰性执行的，过期数据可能一直保留到再次打开上传页面。
* 旧版 V1 上传没有可查询的会话标识，中断后必须由用户在“我的图片”中人工确认。
* 动图支持仍计划在后续版本中提供。
* 针对受支持 Chrome 和 iOS 浏览器矩阵的真实设备验收属于部署验证步骤， 不包含在 jsdom 单元测试中。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://summerain-1.gitbook.io/summerain/zh-cn/fa-bu-shuo-ming/v2.0.2.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
