協同擴充模組

瞭解 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。

模組關係

100%
擴充模組與核心協同的關係
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 中已確認的變更集。

TypeScript
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 的留言本文、回覆、編輯、刪除及已解決狀態:

TypeScript
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 保持精簡。

TypeScript
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 儲存來源檔與結果檔:

TypeScript
const exchangeService = new UniverExchangeService({ collabService, fileService });transport.register(new UniverExchangeEndpoint(exchangeService));

匯入與匯出都是 task:用戶端建立 task 後輪詢結果。匯入經過 Core Service 的 createUnit Middleware,匯出經過 readUnitData Middleware;Exchange 自己的 import 與 export Middleware 用於限流、配額與稽核。

Unit匯入匯出
Sheetxls, xlsx, csv, tsvxlsx, csv, tsv
Docdoc, docxdocx
Slideppt, pptxpptx
Basexls, xlsx, csv, tsvxlsx, csv
PDFpdfpdf

task 保存在 Service 實例內,匯入匯出節點部署一個即可,並把 Exchange 的三條路由都發到這個節點。

Worktree 草稿與合併

Worktree 為一個或多個 Unit 增加隔離草稿、凍結、合併評估與逐 Unit 合併:

text
create → draft → ready → merging → merged           ↑       │           └ reopen┘draft / ready → discarded
TypeScript
const 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 的合併結果。

獨立擴充點

啟用擴充模組時,分別評估每個邊界:

邊界核心HistoryCommentFileWorktree
Service獨立獨立獨立獨立獨立
Middleware不共享不繼承核心不繼承核心不繼承核心不繼承核心
Event核心生命週期觀察核心 EventscommentCommitted—Worktree 生命週期/提交
Database Adapter核心 AdapterHistory AdapterComment AdapterFile Adapter 與 Blob StoreWorktree Adapter

這些 Adapter 可使用同一個資料庫,但仍是具有獨立契約的不同物件。Service 和 Adapter 也應分別釋放。

Office Exchange 重用 Core 與 File 的儲存:它自己的 import、export Middleware 執行後,匯入匯出仍進入 Core 與 File 的 Middleware。

選擇能力

產品需求模組入門範例
使用者可見的版本歷史History Service、Endpoint、Adapterpnpm example:history
Sheet 或 Doc 留言Comment Service、Endpoint、Adapterpnpm example:comments
圖片、附件與檔案儲存File Service、Endpoint、Adapter、Blob Storepnpm example:file-service
服務端 Office 匯入與匯出Exchange Service、Endpoint + Filepnpm example:exchange
隔離草稿、審閱與合併Worktree Service、Endpoint、Client、Adapterpnpm example:worktree

完整執行命令與頁面網址請參閱範例索引。

連接 Web SDK 歷史介面

將 History Endpoint 與協同端點一起掛載。Web SDK 的 historyServerUrl 是 /{unitId}/list、/{unitId}/creators 與 /{unitId}/cs 的共同前綴,預設為 /universer-api/history。若使用其他前綴,請為宿主 History 外掛與品類 History UI 外掛設定相同位址。

還原版本會透過協同 mutation 提交,不是呼叫獨立的歷史還原 REST 介面。請保留協同載入、提交與授權設定。createUnitComparisonEngine() 對兩份完整快照進行唯讀比較,不需要執行歷史服務,也不會儲存或還原版本。

你覺得這篇文檔如何?

© 2026 DreamNum Co., Ltd.