據(jù)庫與通用同步引擎)
RxDB 作為 Replicache 替代方案面向 Local-First Web 應用的文檔數(shù)據(jù)庫與通用同步引擎【免費下載鏈接】rxdbThe local-first database that runs on every JS runtime and replicates with your existing backend - no vendor, no lock-in - https://rxdb.info/項目地址: https://gitcode.com/gh_mirrors/rx/rxdbReplicache 憑借基于 mutator 的同步模型和聚焦協(xié)作 Web 應用的產(chǎn)品定位在 local-first 社區(qū)中建立了影響力。但當項目規(guī)模增長后mutator 架構(gòu)、源碼可用source-available許可證與高度定制的查詢 API 會成為瓶頸。本文以 RxDBReactive Database為對象系統(tǒng)對比兩種方案的架構(gòu)差異并給出無需共享 mutator 的 HTTP/GraphQL 復制實戰(zhàn)示例幫助團隊在選型時做出基于證據(jù)的決策。output文章RxDB 作為 Replicache 替代方案面向 Local-First Web 應用的文檔數(shù)據(jù)庫與通用同步引擎Replicache 在 local-first 社區(qū)中以基于 mutator 的同步模型和聚焦協(xié)作 Web 應用的產(chǎn)品定位建立了影響力。當項目規(guī)模增長后mutator 架構(gòu)、源碼可用許可證與高度定制的查詢 API 會成為擴展瓶頸。本文以 RxDBReactive Database為對象系統(tǒng)對比兩種方案的架構(gòu)差異并給出無需共享 mutator 的 HTTP/GraphQL 復制實戰(zhàn)示例幫助團隊在選型時做出基于證據(jù)的決策。一、Replicache 簡史與核心模型Replicache 由 RocicorpAaron Boodman 與 Erik Arvidsson 創(chuàng)立開發(fā)約 2020 年首次出現(xiàn)長期以源碼可用許可證分發(fā)而非 OSI 批準的開放源碼許可證。2024 年 Rocicorp 宣布 Replicache 免費使用同時下一代產(chǎn)品 Zero有時稱為 Zerosync將同時接替 Replicache 與 Reflect。Replicache 的典型特征是mutator 驅(qū)動模型不是寫本地數(shù)據(jù)庫再通過通用復制協(xié)議推送變更而是定義描述輸入數(shù)據(jù)如何改變狀態(tài)的 mutator 函數(shù)。每個 mutator 先在客戶端運行以獲得即時反饋optimistic UI再到服務端運行產(chǎn)出權(quán)威狀態(tài)。前端通過useSubscribe等 hook 在本地緩存變化時讀取數(shù)據(jù)。這套模型帶來兩個直接約束邏輯必須雙端鏡像同一 mutator 定義必須同時存在于客戶端與服務端且對同一輸入產(chǎn)生相同 deltaAPI 圍繞 mutator 名稱設(shè)計而不是圍繞 collection、查詢或 REST 資源設(shè)計。二、RxDB 是什么RxDBReactive Database是一個 JavaScript 數(shù)據(jù)庫文檔存儲在本地 RxCollection 中并在其上暴露 響應式查詢。它運行在瀏覽器、Node.js、Electron 與 React Native 中。本地存儲是 UI 的事實來源同步引擎 保持本地與遠端一致。RxDB 以 Apache 2.0 許可證分發(fā)核心代碼完全開源可審計另提供可選的高級插件。關(guān)鍵屬性文檔模型JSON schema 索引MongoDB 風格查詢語言RxQuery基于 RxJS Observable 的響應式結(jié)果可插拔存儲層IndexedDB、OPFS、SQLite、內(nèi)存等復制能力HTTP、GraphQL、CouchDB、Firestore、WebRTC 及自定義傳輸每個 collection 可自定義 沖突處理器。三、Replicache 的五個痛點1. Mutator 架構(gòu)強制共享邏輯每次寫入都要經(jīng)過 mutator且函數(shù)定義必須在客戶端與服務端同時存在并產(chǎn)出相同結(jié)果。已擁有 REST/GraphQL 后端的團隊要么把現(xiàn)有端點包進 mutator要么在客戶端重寫業(yè)務邏輯。RxDB 則把本地 collection 當作普通數(shù)據(jù)庫寫入在本地發(fā)生復制協(xié)議 把變更發(fā)給任意現(xiàn)有端點。2. 許可證歷史源碼可用而非開源2024 年前Replicache 大部分歷史采用源碼可用許可證免費使用限制在非商業(yè)項目、營收低于 20 萬美元且融資低于 50 萬美元的公司。2024 年公告使其免費但長期產(chǎn)品投入已轉(zhuǎn)向 Zero。RxDB 從項目伊始就是 Apache 2.0核心不設(shè)收入門檻。3. 高度定制的查詢 APIReplicache 通過 key/value 掃描與useSubscribe讀取數(shù)據(jù)沒有內(nèi)置 MongoDB 風格操作符、schema 定義的二級索引或聚合能力任何類似查詢的東西都需在掃描 API 之上用 JavaScript 組裝。RxDB 提供完整 RxQuery 引擎$gt、$in、$regex、排序、limit、索引查找以及可觀察結(jié)果。4. 服務端狀態(tài)完全自理Replicache 提供同步協(xié)議但期望你自行維護服務端權(quán)威狀態(tài)版本追蹤、客戶端組、patch 生成。RxDB 的 pull/push handler 只是返回文檔與 checkpoint 的簡單異步函數(shù)服務端可以是現(xiàn)有數(shù)據(jù)庫上的薄封裝、存儲過程或 CouchDB 實例。5. 無一方 Peer-to-PeerReplicache 是純 client-server 協(xié)議。RxDB 內(nèi)置 WebRTC 復制插件peer 之間可直接同步而無需中央服務器。四、為什么團隊轉(zhuǎn)向 RxDBApache 2.0 許可證核心無收入門檻文檔數(shù)據(jù)庫JSON schema 校驗與類型化查詢可觀察查詢底層數(shù)據(jù)變化時 UI 自動更新任意端點復制包括 HTTP、GraphQL、CouchDB、Firestore 與 WebRTC多存儲同一套代碼在瀏覽器用 IndexedDB、React Native 用 SQLite、測試用內(nèi)存存儲無需 mutator 定義寫入就是 collection 上的普通insert、patch、remove調(diào)用可控沖突處理每個 collection 可自定義沖突處理器實時行為通過 響應式查詢引擎 實現(xiàn)。五、代碼示例無共享 mutator 的 HTTP 復制以下示例創(chuàng)建 collection 并針對普通 REST 端點復制。服務端只需在 push 時接受一批文檔、在 pull 時返回新文檔加 checkpoint無需與客戶端共享任何 mutator。import { createRxDatabase } from rxdb/plugins/core; import { getRxStorageLocalstorage } from rxdb/plugins/storage-localstorage; import { replicateRxCollection } from rxdb/plugins/replication; const db await createRxDatabase({ name: app, storage: getRxStorageLocalstorage() }); await db.addCollections({ todos: { schema: { title: todo schema, version: 0, primaryKey: id, type: object, properties: { id: { type: string, maxLength: 100 }, text: { type: string }, done: { type: boolean }, updatedAt: { type: number } }, required: [id, text, done, updatedAt] } } }); replicateRxCollection({ collection: db.todos, replicationIdentifier: todos-http, live: true, pull: { async handler(checkpoint, batchSize) { const url https://api.example.com/todos/pull?cp${ encodeURIComponent(JSON.stringify(checkpoint || {})) }limit${batchSize}; const res await fetch(url); const body await res.json(); return { documents: body.documents, checkpoint: body.checkpoint }; } }, push: { async handler(changeRows) { const res await fetch(https://api.example.com/todos/push, { method: POST, headers: { content-type: application/json }, body: JSON.stringify(changeRows) }); return await res.json(); } } }); // 普通寫入無需 mutator await db.todos.insert({ id: t1, text: Try RxDB, done: false, updatedAt: Date.now() });同一 collection 可通過更換復制插件接入 GraphQL 端點、CouchDB 服務器或自定義 WebSocket 流collection API 保持不變。5.1 參數(shù)與底層機制解讀replicationIdentifier在 src/plugins/replication/index.ts 中它是必填標識用于生成 meta 存儲實例名與修訂版本標記deletedField默認_deleted。live: true實時復制retryTime默認 5000ms失敗后按此間隔重試autoStart默認 true。pull.batchSize與push.batchSize默認 100在 src/plugins/replication/index.ts 中傳入底層復制協(xié)議。checkpoint 持久化協(xié)議把每個方向upstream/downstream的 checkpoint 寫入 meta 實例僅當內(nèi)容變化時才寫入見 src/replication-protocol/checkpoint.ts。核心協(xié)議在 src/replication-protocol/index.tsreplicateRxStorageInstance分別啟動startReplicationDownstreampull 方向與startReplicationUpstreampush 方向。生命周期 APIawaitInitialReplication()、awaitInSync()、reSync()、pause()、cancel()、remove()以及received$、sent$、error$、conflict$等可觀察事件均定義于 src/plugins/replication/index.ts。六、代碼示例在 React 中訂閱查詢Replicache 通過useSubscribe暴露掃描 API。RxDB 暴露完整查詢語言并返回 ObservableReact 可直接消費。import { useEffect, useState } from react; import { RxDocument } from rxdb; type Todo { id: string; text: string; done: boolean; updatedAt: number; }; export function OpenTodos({ db }) { const [todos, setTodos] useStateRxDocumentTodo[]([]); useEffect(() { const sub db.todos .find({ selector: { done: false }, sort: [{ updatedAt: desc }] }) .$.subscribe(results setTodos(results)); return () sub.unsubscribe(); }, [db]); return ( ul {todos.map(t ( li key{t.id} onClick{() t.patch({ done: true })} {t.text} /li ))} /ul ); }查詢是聲明式的patch是文檔上的普通寫入。樂觀 UI 行為來自本地存儲詳細說明見 樂觀 UI 指南。6.1 React 綁定與源碼佐證倉庫還提供了封裝好的官方 React 插件src/plugins/react與手寫訂閱等價import { useLiveRxQuery } from rxdb/plugins/react; const { results, loading, error } useLiveRxQuery({ collection: db.todos, query: { selector: { done: false }, sort: [{ updatedAt: desc }] } });useLiveRxQuery與useRxQuery都基于useRxQueryBase內(nèi)部用collection.find(query)構(gòu)造 RxQuerylive: true時訂閱rxQuery.$否則調(diào)用rxQuery.exec()一次并把結(jié)果、loading、error 三個狀態(tài)暴露給組件見 src/plugins/react/hooks/use-rx-query.ts 與 src/plugins/react/hooks/use-live-rx-query.ts。七、Mutators vs Documents兩種心智模型兩者的根本差異是心智模型。Replicache 把每次變更視為一次命名操作addTodo({ id, text })這樣的 mutator 是唯一變更狀態(tài)的方式??蛻舳藢Ρ镜鼐彺孢\行 mutator 獲得即時結(jié)果服務端運行同一 mutator 產(chǎn)出權(quán)威狀態(tài)協(xié)議協(xié)調(diào)兩者。應用邏輯存在于 mutator 內(nèi)部讀取則是對 key/value 存儲的掃描。RxDB 把每次變更視為對 collection 中文檔的一次寫入調(diào)用collection.insert、doc.patch或collection.bulkUpsert。本地存儲記錄變更同步引擎 通過通用 push handler 把變更發(fā)往服務端服務端存入任意現(xiàn)有數(shù)據(jù)庫。讀取是帶響應式結(jié)果的 MongoDB 風格查詢。實際后果后端復用RxDB 接入現(xiàn)有 REST/GraphQL/SQL 后端無需把端點改名以匹配 mutator 語義Schema 驅(qū)動存儲RxDB 用 JSON schema 校驗文檔Replicache 存儲以字符串為 key 的任意 JSON 值查詢表達能力RxDB 支持操作符、排序與索引Replicache 需要手動掃描和過濾沖突處理RxDB 可為每個 collection 編寫 自定義沖突處理器Replicache 通過 mutator 重放合并。兩種模型并無絕對優(yōu)劣。mutator 適合緊密耦合的協(xié)作編輯文檔模型適合通用應用數(shù)據(jù)、離線優(yōu)先應用和現(xiàn)有后端。7.1 沖突處理的源碼實現(xiàn)倉庫的默認沖突處理器src/replication-protocol/default-conflict-handler.ts用deepEqual判斷兩文檔是否相等相等即無沖突解析沖突時總是丟棄 fork 狀態(tài)、采用 master 狀態(tài)。自定義處理器只需實現(xiàn)isEqual(a, b, ctx)與resolve(conflict)兩個方法例如只比較updatedAt時間戳以提升性能。沖突在 push 階段由 master 側(cè)檢測并返回見 src/replication-protocol/index.ts。八、FAQRxDB 是開源的嗎是。RxDB 核心以 Apache 2.0 許可證分發(fā)源碼公開。數(shù)據(jù)庫、查詢引擎與復制協(xié)議全部開源無收入門檻僅高級存儲與企業(yè)功能為可選付費插件。RxDB 需要寫 mutator 嗎不需要。RxDB 使用insert、patch、bulkUpsert、remove等常規(guī) collection 方法復制協(xié)議通過 pull/push handler 把變更轉(zhuǎn)發(fā)給后端。如需集中寫邏輯可用輔助函數(shù)封裝但數(shù)據(jù)庫本身不強制。RxDB 能擴展到大量客戶端嗎可以。復制協(xié)議基于 checkpoint每個客戶端只拉取上次同步之后的變更。服務端可以是任何暴露 pull/push 端點的系統(tǒng)橫向擴展等價于擴展現(xiàn)有 API。RxDB 還提供 WebRTC 復制 支持 P2P 場景。Zero / Zerosync 呢Zero 是 Rocicorp 接替 Replicache 與 Reflect 的產(chǎn)品有獨立協(xié)議與權(quán)衡。RxDB 不是 Zero 的 drop-in 移植但覆蓋同樣的 local-first 用例響應式查詢 同步。RxDB 已穩(wěn)定多年、Apache 2.0 發(fā)布且能與任意現(xiàn)有后端協(xié)作。RxDB 支持 NextJS、Remix 與 React Native 嗎支持。RxDB 運行在任何 JavaScript 環(huán)境。NextJS/Remix 中在瀏覽器側(cè)實例化數(shù)據(jù)庫并用 React 綁定訂閱查詢React Native 中選擇 SQLite 等原生存儲。同一套 collection 定義與查詢在所有環(huán)境通用。九、對比一覽FeatureReplicacheRxDB許可證源碼可用2024 年起免費Apache 2.0開源數(shù)據(jù)模型Key/value 存儲帶 JSON schema 的文檔 collection寫入客戶端服務端 mutator 函數(shù)直接insert/patch/remove查詢 API掃描之上的useSubscribeMongoDB 風格 RxQuery響應式結(jié)果是是通過 RxJS Observables服務端要求實現(xiàn) mutator 與 patch API實現(xiàn) pull/push handler存儲選項IndexedDBIndexedDB、OPFS、SQLite、內(nèi)存等沖突解決mutator 重放每 collection 自定義 handlerP2P 同步否是WebRTC傳輸Replicache 協(xié)議HTTP、GraphQL、CouchDB、Firestore、WebRTC運行時瀏覽器、React Native瀏覽器、Node.js、Electron、React Native十、結(jié)論與后續(xù)資源如果 Replicache 的 mutator 架構(gòu)或歷史許可證條款阻塞了項目RxDB 是一個直接替代方案保留 local-first 開發(fā)體驗補上真正的文檔數(shù)據(jù)庫與響應式查詢并與現(xiàn)有后端任意同步。延伸閱讀RxDB 同步引擎HTTP 復制GraphQL 復制RxQuery響應式?jīng)_突解決Local-First 的未來實時數(shù)據(jù)庫 /output文章【免費下載鏈接】rxdbThe local-first database that runs on every JS runtime and replicates with your existing backend - no vendor, no lock-in - https://rxdb.info/項目地址: https://gitcode.com/gh_mirrors/rx/rxdb創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考