協同擴充模組
瞭解 History、Thread Comment、Worktree、File 和服務端 Office 檔案轉換如何擴充核心協同。
History、Thread Comment、File 和 Worktree 是可按需啟用的獨立協同擴充模組。它們可重用 Transport、身分系統及實體資料庫,但各自保有 Service、Middleware、Event、Database Adapter 與生命週期邊界。
服務端 Office 檔案轉換組合 File 與 Collaboration Service:它在 Office 檔案與協同 Unit 之間轉換,擁有自己的 Service、Endpoint 與 Middleware。
模組關係
| 擴充模組 | 與核心協同的關係 |
|---|---|
| History | 觀察核心 Events,建立衍生歷史索引 |
| Thread Comment | 重用核心 Unit Room;留言錨點屬於核心內容 |
| File | 儲存 Unit 引用的圖片、附件與匯入匯出檔案,Unit 資料只記錄檔案 ID |
| Office Exchange | 透過核心 Service 建立或讀取 Unit,透過 File 讀寫檔案 |
| Worktree | 重用核心 Unit 與 OT 能力,將草稿合併到主幹 |
History、Thread Comment、File 和 Worktree 各自設定 Middleware、Events 與 Database Adapter。
版本歷史
History 將 Unit 建立及已確認變更集分組為使用者可見的歷史項目。它是衍生索引:Unit 內容的權威來源仍是核心 Collaboration Service 中已確認的變更集。
const historyService = new UniverHistoryService({ collabService, dbAdapter: historyDatabase, userProvider,});transport.register(new UniverHistoryEndpoint(historyService));建構 History Service 時即訂閱核心 Service 的 unitCreated 和 changesetCommitted Events 並更新索引。dispose() 會解除這些訂閱。預設策略按時間視窗與特殊 mutation 分組,而非每個變更集建立一筆歷史。
History 提供 getHistoryList、listHistoryCreators 與 getHistoryChangesets 讀取 Middleware。索引由 Service 在內部維護。userProvider 只補充名稱、頭像等顯示資料,不負責驗證或授權。Event Listener 失敗不會回滾已確認的核心變更集,因此應始終將 History 視為可重建的衍生資料。
討論串留言
Comment Service 管理 Sheets 和 Docs 的留言本文、回覆、編輯、刪除及已解決狀態:
const commentService = new UniverCommentService({ database: commentDatabase, userProvider,});transport.register( new UniverCommentEndpoint({ service: commentService, roomHost: collabEndpoint, }),);留言本文屬於 Comment Adapter。隨 Sheet 或 Doc 內容移動的錨點仍屬於核心快照與變更集。Comment Endpoint 可透過主 Collaboration Endpoint 的 Unit Room 發布 comment_update,但即時訊息不是權威留言狀態;用戶端可重新取得留言清單以還原。
Comment Service 提供新增、清單、回覆、解決/重新開啟、編輯、刪除的 Middleware,以及 commentCommitted Event。它不繼承核心 Service 的讀取或編輯策略。
檔案儲存
File 儲存 Univer 用戶端上傳的二進位檔案:插入 Unit 的圖片和附件,以及匯入匯出的來源檔與結果檔。Unit 資料只記錄檔案 ID,載入時用戶端用 ID 換取下載網址,snapshot 與 changeset 保持精簡。
const fileService = new UniverFileService({ database: fileDatabase, blobStore,});transport.register(new UniverFileEndpoint(fileService));中繼資料與內容是兩個獨立契約:IFileDatabaseAdapter 儲存檔案記錄,IFileBlobStore 儲存內容。匯入匯出的暫存檔只有上傳者可以存取,並由 Service 定期清理;Unit 的圖片與附件透過 upload、signUrl、download Middleware 按 Unit 權限控制。
服務端 Office 檔案轉換
Exchange Service 把 Office 檔案匯入為協同 Unit,並把 Unit 匯出為檔案。它依賴 @univerjs-pro/exchange-node 轉換,透過 Collaboration Service 建立和讀取 Unit,透過 File Service 儲存來源檔與結果檔:
const exchangeService = new UniverExchangeService({ collabService, fileService });transport.register(new UniverExchangeEndpoint(exchangeService));匯入與匯出都是 task:用戶端建立 task 後輪詢結果。匯入經過 Core Service 的 createUnit Middleware,匯出經過 readUnitData Middleware;Exchange 自己的 import 與 export Middleware 用於限流、配額與稽核。
| Unit | 匯入 | 匯出 |
|---|---|---|
| Sheet | xls, xlsx, csv, tsv | xlsx, csv, tsv |
| Doc | doc, docx | docx |
| Slide | ppt, pptx | pptx |
| Base | xls, xlsx, csv, tsv | xlsx, csv |
task 保存在 Service 實例內,匯入匯出節點部署一個即可,並把 Exchange 的三條路由都發到這個節點。
Worktree 草稿與合併
Worktree 為一個或多個 Unit 增加隔離草稿、凍結、合併評估與逐 Unit 合併:
create → draft → ready → merging → merged ↑ │ └ reopen┘draft / ready → discardedconst worktreeService = new UniverCollabWorktreeService({ trunk: { service: collabService, dbAdapter: coreDatabase, }, dbAdapter: worktreeDatabase,});Worktree 以 (worktreeID, unitID) 儲存獨立草稿變更集,同時重用核心 Service 的 Unit、OT 與提交引擎。只有 draft 狀態接受後續編輯。markReady() 凍結目前草稿修訂版本,mergeWorktree() 將 Unit 逐一合併到主幹。
Worktree Service 有獨立的生命週期、讀取、草稿 submit/apply/commit Middleware,以及建立、狀態變更、合併結果、草稿變更集提交的 Events。最終寫入主幹仍會通過核心 Service 自身的 Middleware。
多 Unit 合併並非跨 Unit 原子操作。應用應顯示每個 Unit 的合併結果。
獨立擴充點
啟用擴充模組時,分別評估每個邊界:
| 邊界 | 核心 | History | Comment | File | Worktree |
|---|---|---|---|---|---|
| Service | 獨立 | 獨立 | 獨立 | 獨立 | 獨立 |
| Middleware | 不共享 | 不繼承核心 | 不繼承核心 | 不繼承核心 | 不繼承核心 |
| Event | 核心生命週期 | 觀察核心 Events | commentCommitted | — | Worktree 生命週期/提交 |
| Database Adapter | 核心 Adapter | History Adapter | Comment Adapter | File Adapter 與 Blob Store | Worktree Adapter |
這些 Adapter 可使用同一個資料庫,但仍是具有獨立契約的不同物件。Service 和 Adapter 也應分別釋放。
Office Exchange 重用 Core 與 File 的儲存:它自己的 import、export Middleware 執行後,匯入匯出仍進入 Core 與 File 的 Middleware。
選擇能力
| 產品需求 | 模組 | 入門範例 |
|---|---|---|
| 使用者可見的版本歷史 | History Service、Endpoint、Adapter | pnpm example:history |
| Sheet 或 Doc 留言 | Comment Service、Endpoint、Adapter | pnpm example:comments |
| 圖片、附件與檔案儲存 | File Service、Endpoint、Adapter、Blob Store | pnpm example:file-service |
| 服務端 Office 匯入與匯出 | Exchange Service、Endpoint + File | pnpm example:exchange |
| 隔離草稿、審閱與合併 | Worktree Service、Endpoint、Client、Adapter | pnpm example:worktree |
完整執行命令與頁面網址請參閱範例索引。
連接 Web SDK 歷史介面
將 History Endpoint 與協同端點一起掛載。Web SDK 的 historyServerUrl 是 /{unitId}/list、/{unitId}/creators 與 /{unitId}/cs 的共同前綴,預設為 /universer-api/history。若使用其他前綴,請為宿主 History 外掛與品類 History UI 外掛設定相同位址。
還原版本會透過協同 mutation 提交,不是呼叫獨立的歷史還原 REST 介面。請保留協同載入、提交與授權設定。createUnitComparisonEngine() 對兩份完整快照進行唯讀比較,不需要執行歷史服務,也不會儲存或還原版本。
你覺得這篇文檔如何?