@univerjs-pro/collaboration-history-database-sqlite 1.0.0-rc.0 → 1.0.1

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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  English | [简体中文](./README.zh-CN.md)
4
4
 
5
- A persistent SQLite `IHistoryDatabaseAdapter` for `@univerjs-pro/collaboration-history-service`. It uses the stable synchronous `libsql` API, supports Node.js 22 and later, and can share a database file with the core, Comment, and Worktree SQLite Adapters.
5
+ A persistent SQLite `IHistoryDatabaseAdapter` for `@univerjs-pro/collaboration-history-service`. It supports Node.js 22 and later and can share a database file with Core, Comment, and Worktree.
6
6
 
7
7
  ## Installation and usage
8
8
 
@@ -13,6 +13,9 @@ pnpm add \
13
13
  ```
14
14
 
15
15
  ```ts
16
+ import { UniverHistoryService } from '@univerjs-pro/collaboration-history-service';
17
+ import { SQLiteHistoryDatabaseAdapter } from '@univerjs-pro/collaboration-history-database-sqlite';
18
+
16
19
  const historyDatabase = new SQLiteHistoryDatabaseAdapter({
17
20
  filename: './data/collaboration.sqlite',
18
21
  busyTimeoutMs: 5_000,
@@ -22,18 +25,22 @@ const historyService = new UniverHistoryService({
22
25
  dbAdapter: historyDatabase,
23
26
  });
24
27
 
25
- historyService.attach(collabService);
26
-
27
28
  await historyService.dispose();
28
29
  await historyDatabase.dispose();
29
30
  ```
30
31
 
31
32
  The caller must create the database parent directory in advance and dispose the Adapter after stopping the Service.
32
33
 
33
- ## Storage contract
34
+ Empty databases are initialized automatically. The application coordinates History cleanup when permanently deleting a Unit.
35
+
36
+ ## Migration from v1 to v2
37
+
38
+ Migrate a v1 database before opening it with this Adapter. Stop writers and back up the database, then run:
34
39
 
35
- - History data uses `collaboration_history_revisions`.
36
- - Schema version `('history', 1)` is stored in shared `collaboration_schema_versions`; `PRAGMA user_version` is not used.
37
- - An empty History schema is initialized automatically. Incomplete or unsupported schemas are rejected without migration or legacy fallback.
40
+ ```ts
41
+ import { migrateSQLiteHistoryV1ToV2 } from '@univerjs-pro/collaboration-history-database-sqlite';
42
+
43
+ await migrateSQLiteHistoryV1ToV2({ filename: './data/collaboration.sqlite' });
44
+ ```
38
45
 
39
- History is a derived index. A core collaboration hard delete does not automatically delete History; the application must coordinate cross-module cleanup when required.
46
+ Migrate older Core and Worktree schemas in the same file first. The migration preserves existing History and rolls back on failure. Restore the backup to downgrade.
package/README.zh-CN.md CHANGED
@@ -3,8 +3,8 @@
3
3
  [English](./README.md) | [简体中文](./README.zh-CN.md)
4
4
 
5
5
  面向 `@univerjs-pro/collaboration-history-service` 的持久化 SQLite
6
- `IHistoryDatabaseAdapter`。它使用稳定的 `libsql` 同步接口,支持 Node.js 22 及以上,
7
- 并可与 core、Comment 和 Worktree SQLite Adapter 共用一个数据库文件。
6
+ `IHistoryDatabaseAdapter`。支持 Node.js 22 及以上,可与 Core、Comment 和 Worktree
7
+ 共用一个数据库文件。
8
8
 
9
9
  ## 安装与使用
10
10
 
@@ -15,6 +15,9 @@ pnpm add \
15
15
  ```
16
16
 
17
17
  ```ts
18
+ import { UniverHistoryService } from '@univerjs-pro/collaboration-history-service';
19
+ import { SQLiteHistoryDatabaseAdapter } from '@univerjs-pro/collaboration-history-database-sqlite';
20
+
18
21
  const historyDatabase = new SQLiteHistoryDatabaseAdapter({
19
22
  filename: './data/collaboration.sqlite',
20
23
  busyTimeoutMs: 5_000,
@@ -24,21 +27,23 @@ const historyService = new UniverHistoryService({
24
27
  dbAdapter: historyDatabase,
25
28
  });
26
29
 
27
- historyService.attach(collabService);
28
-
29
30
  await historyService.dispose();
30
31
  await historyDatabase.dispose();
31
32
  ```
32
33
 
33
34
  调用方必须预先创建数据库父目录,并在 Service 停止后释放 Adapter。
34
35
 
35
- ## 存储契约
36
+ 空库自动初始化。永久删除 Unit 时,由应用协调清理 History 数据。
37
+
38
+ ## v1 → v2 迁移
39
+
40
+ 使用此 Adapter 打开 v1 数据库前需先迁移。停止写入并备份后执行:
36
41
 
37
- - History 数据使用 `collaboration_history_revisions`。
38
- - schema 版本 `('history', 1)` 记录在共享的
39
- `collaboration_schema_versions`,不占用 `PRAGMA user_version`。
40
- - 空 History schema 自动初始化;不完整或不支持的 schema 会被拒绝,不执行 migration
41
- 或 legacy fallback。
42
+ ```ts
43
+ import { migrateSQLiteHistoryV1ToV2 } from '@univerjs-pro/collaboration-history-database-sqlite';
44
+
45
+ await migrateSQLiteHistoryV1ToV2({ filename: './data/collaboration.sqlite' });
46
+ ```
42
47
 
43
- History 是派生索引。协同 core hard delete 不会自动删除 History;需要跨模块清理时由应用
44
- 统一协调。
48
+ 同文件中的旧版 Core 和 Worktree 应先完成迁移。迁移保留已有历史,失败时整体回滚。
49
+ 降级需恢复备份。
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object['defineProperty'](exports,Symbol['toStringTag'],{'value':'Module'});var e=Object['create'],t=Object['defineProperty'],n=Object['getOwnPropertyDescriptor'],r=Object['getOwnPropertyNames'],i=Object['getPrototypeOf'],a=Object['prototype']['hasOwnProperty'],o=(_0x24e071,_0x5cea5e,_0x5ed6b8,_0x57d8f0)=>{if(_0x5cea5e&&typeof _0x5cea5e=='object'||typeof _0x5cea5e=='function'){for(var _0x3a43b4=r(_0x5cea5e),_0x5c9587=0x0,_0x2ebc30=_0x3a43b4['length'],_0x775ebe;_0x5c9587<_0x2ebc30;_0x5c9587++)_0x775ebe=_0x3a43b4[_0x5c9587],!a['call'](_0x24e071,_0x775ebe)&&_0x775ebe!==_0x5ed6b8&&t(_0x24e071,_0x775ebe,{'get':(_0xe46680=>_0x5cea5e[_0xe46680])['bind'](null,_0x775ebe),'enumerable':!(_0x57d8f0=n(_0x5cea5e,_0x775ebe))||_0x57d8f0['enumerable']});}return _0x24e071;},s=(_0x15f4f6,_0xcd0b,_0xc8d47e)=>(_0xc8d47e=_0x15f4f6==null?{}:e(i(_0x15f4f6)),o(_0xcd0b||!_0x15f4f6||!_0x15f4f6['__esModule']?t(_0xc8d47e,'default',{'value':_0x15f4f6,'enumerable':!0x0}):_0xc8d47e,_0x15f4f6));let c=require('libsql');c=s(c,0x1);let l=require('@univerjs-pro/collaboration-history-service');var u=0x1388,d='history',f=0x1,p=['collaboration_history_revisions'],m=class{['_database'];['_disposed']=!0x1;constructor(_0x3b3cd4){g(_0x3b3cd4),this['_database']=new c['default'](_0x3b3cd4['filename'],{'timeout':_0x3b3cd4['busyTimeoutMs']??u});try{this['_database']['exec']('PRAGMA\x20busy_timeout\x20=\x20'+(_0x3b3cd4['busyTimeoutMs']??u)+';'),this['_initializeSchema']();}catch(_0x33b59f){throw this['_database']['close'](),_0x33b59f;}}async['getIndexState'](_0x1265fc){this['_assertOpen']();let _0x555420=this['_latestEntry'](_0x1265fc);if(!_0x555420)return null;let _0x631407=this['_getEntry'](_0x1265fc,_0x555420['historyRevision']);if(!_0x631407)throw Error('SQLite\x20History\x20contains\x20an\x20invalid\x20history\x20revision');return{'unitID':_0x1265fc,'type':_0x555420['type'],'latestRevision':_0x555420['revision'],'currentHistoryRevision':_0x555420['historyRevision'],'currentHistoryCreatedAt':_0x631407['committedAt'],'forceNextHistory':_0x555420['forceNextHistory']};}async['getRevision'](_0x51114b,_0x1cb522){return this['_assertOpen'](),this['_getEntry'](_0x51114b,_0x1cb522);}async['appendRevision'](_0x48f152,_0x2bcedc){return this['_assertOpen'](),v(_0x48f152),this['_transaction'](()=>{if(this['_getEntry'](_0x48f152['unitID'],_0x48f152['revision']))return{'status':'already-indexed'};let _0x10ff2f=this['_database']['prepare']('SELECT\x20revision\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20collaboration_history_revisions\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20unit_id\x20=\x20?\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20revision\x20DESC\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20LIMIT\x201')['get'](_0x48f152['unitID'])?.['revision']??0x0;return _0x10ff2f!==_0x2bcedc['expectedLatestRevision']||_0x48f152['revision']!==_0x10ff2f+0x1?{'status':'revision-conflict','actualLatestRevision':_0x10ff2f}:(this['_database']['prepare']('INSERT\x20INTO\x20collaboration_history_revisions\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20(unit_id,\x20type,\x20revision,\x20user_id,\x20commands_json,\x20committed_at,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20additional_fields,\x20origin,\x20history_revision,\x20force_next_history,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20restored_revision)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20VALUES\x20(?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?,\x20?)')['run'](_0x48f152['unitID'],_0x48f152['type'],_0x48f152['revision'],_0x48f152['userID'],JSON['stringify'](_0x48f152['commands']),_0x48f152['committedAt'],_0x48f152['additionalFields']??null,_0x48f152['origin'],_0x48f152['historyRevision'],+!!_0x48f152['forceNextHistory'],_0x48f152['restoredRevision']??null),{'status':'appended'});});}async['listRecords'](_0x27790a,_0x1f51c3){return this['_assertOpen'](),(0x0,l['selectHistoryRecords'])((0x0,l['buildHistoryRecords'])(this['_database']['prepare']('SELECT\x20unit_id,\x20type,\x20revision,\x20user_id,\x20commands_json,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20committed_at,\x20additional_fields,\x20origin,\x20history_revision,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20force_next_history,\x20restored_revision\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20collaboration_history_revisions\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20unit_id\x20=\x20?\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20revision\x20ASC')['all'](_0x27790a)['map'](h)),_0x1f51c3);}async['listCreators'](_0x504fbb){this['_assertOpen']();let _0x2a527d=this['_database']['prepare']('SELECT\x20unit_id,\x20type,\x20revision,\x20user_id,\x20commands_json,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20committed_at,\x20additional_fields,\x20origin,\x20history_revision,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20force_next_history,\x20restored_revision\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20collaboration_history_revisions\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20unit_id\x20=\x20?\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20revision\x20ASC')['all'](_0x504fbb)['map'](h),_0x3b826f=new Map();for(let _0x236550 of _0x2a527d){let _0x1d1fd2=_0x3b826f['get'](_0x236550['userID'])??new Set();_0x1d1fd2['add'](_0x236550['origin']),_0x3b826f['set'](_0x236550['userID'],_0x1d1fd2);}return[..._0x3b826f]['map'](([_0x8ab838,_0x22ac75])=>({'userID':_0x8ab838,'origins':[..._0x22ac75]}));}async['dispose'](){this['_disposed']||(this['_disposed']=!0x0,this['_database']['close']());}['_initializeSchema'](){this['_transaction'](()=>{if(!this['_hasTable']('collaboration_schema_versions')){if(this['_hasAnyOwnedTable']())throw _('SQLite\x20History\x20tables\x20exist\x20without\x20a\x20schema\x20version');this['_database']['exec']('\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20CREATE\x20TABLE\x20collaboration_schema_versions\x20(\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20component\x20TEXT\x20PRIMARY\x20KEY,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20version\x20INTEGER\x20NOT\x20NULL\x20CHECK\x20(version\x20>=\x201)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20);\x0a\x20\x20\x20\x20\x20\x20\x20\x20');}let _0x20a93d=this['_database']['prepare']('SELECT\x20version\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20collaboration_schema_versions\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20component\x20=\x20?')['get'](d);if(_0x20a93d){if(_0x20a93d['version']!==f)throw _('SQLite\x20History\x20schema\x20version\x20'+_0x20a93d['version']+'\x20is\x20not\x20supported');let _0x33613a=p['filter'](_0x10c7da=>!this['_hasTable'](_0x10c7da));if(_0x33613a['length']>0x0)throw _('SQLite\x20History\x20schema\x20v1\x20is\x20incomplete:\x20missing\x20'+_0x33613a['join'](',\x20'));return;}if(this['_hasAnyOwnedTable']())throw _('SQLite\x20History\x20tables\x20exist\x20without\x20a\x20schema\x20version');this['_database']['exec']('\x0a\x20\x20\x20\x20\x20\x20\x20\x20CREATE\x20TABLE\x20collaboration_history_revisions\x20(\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20unit_id\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20type\x20INTEGER\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20revision\x20INTEGER\x20NOT\x20NULL\x20CHECK\x20(revision\x20>=\x201),\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20user_id\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20commands_json\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20committed_at\x20INTEGER\x20NOT\x20NULL\x20CHECK\x20(committed_at\x20>=\x200),\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20additional_fields\x20TEXT,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20origin\x20INTEGER\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20history_revision\x20INTEGER\x20NOT\x20NULL\x20CHECK\x20(history_revision\x20>=\x201),\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20force_next_history\x20INTEGER\x20NOT\x20NULL,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20restored_revision\x20INTEGER,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20PRIMARY\x20KEY\x20(unit_id,\x20revision)\x0a\x20\x20\x20\x20\x20\x20\x20\x20);\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20CREATE\x20INDEX\x20collaboration_history_record_lookup\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20collaboration_history_revisions(unit_id,\x20history_revision\x20DESC);\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20CREATE\x20INDEX\x20collaboration_history_creator_lookup\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20collaboration_history_revisions(unit_id,\x20user_id);\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20INSERT\x20INTO\x20collaboration_schema_versions\x20(component,\x20version)\x0a\x20\x20\x20\x20\x20\x20\x20\x20VALUES\x20(\x27history\x27,\x201);\x0a\x20\x20\x20\x20\x20\x20');});}['_hasTable'](_0x19f8cb){return!!this['_database']['prepare']('SELECT\x201\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20sqlite_schema\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20type\x20=\x20\x27table\x27\x20AND\x20name\x20=\x20?')['get'](_0x19f8cb);}['_hasAnyOwnedTable'](){return p['some'](_0x45fa95=>this['_hasTable'](_0x45fa95));}['_latestEntry'](_0x266344){let _0x4d170d=this['_database']['prepare']('SELECT\x20unit_id,\x20type,\x20revision,\x20user_id,\x20commands_json,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20committed_at,\x20additional_fields,\x20origin,\x20history_revision,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20force_next_history,\x20restored_revision\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20collaboration_history_revisions\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20unit_id\x20=\x20?\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20revision\x20DESC\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20LIMIT\x201')['get'](_0x266344);return _0x4d170d?h(_0x4d170d):null;}['_getEntry'](_0x548c5c,_0x430882){let _0x237ece=this['_database']['prepare']('SELECT\x20unit_id,\x20type,\x20revision,\x20user_id,\x20commands_json,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20committed_at,\x20additional_fields,\x20origin,\x20history_revision,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20force_next_history,\x20restored_revision\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20collaboration_history_revisions\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20unit_id\x20=\x20?\x20AND\x20revision\x20=\x20?')['get'](_0x548c5c,_0x430882);return _0x237ece?h(_0x237ece):null;}['_transaction'](_0x5bb8c8){this['_database']['exec']('BEGIN\x20IMMEDIATE;');try{let _0x57cc97=_0x5bb8c8();return this['_database']['exec']('COMMIT;'),_0x57cc97;}catch(_0x378bb2){try{this['_database']['exec']('ROLLBACK;');}catch{}throw _0x378bb2;}}['_assertOpen'](){if(this['_disposed'])throw Error('SQLite\x20History\x20Database\x20Adapter\x20is\x20disposed');}};function h(_0x127f68){let _0x1de54d=JSON['parse'](_0x127f68['commands_json']);if(!Array['isArray'](_0x1de54d)||_0x1de54d['some'](_0x325508=>typeof _0x325508!='string'))throw Error('SQLite\x20History\x20contains\x20invalid\x20commands');if(_0x127f68['origin']!==0x0&&_0x127f68['origin']!==0x1&&_0x127f68['origin']!==0x2)throw Error('SQLite\x20History\x20contains\x20an\x20invalid\x20origin');return{'unitID':_0x127f68['unit_id'],'type':_0x127f68['type'],'revision':_0x127f68['revision'],'userID':_0x127f68['user_id'],'commands':_0x1de54d,'committedAt':_0x127f68['committed_at'],..._0x127f68['additional_fields']===null?{}:{'additionalFields':_0x127f68['additional_fields']},'origin':_0x127f68['origin'],'historyRevision':_0x127f68['history_revision'],'forceNextHistory':_0x127f68['force_next_history']===0x1,..._0x127f68['restored_revision']===null?{}:{'restoredRevision':_0x127f68['restored_revision']}};}function g(_0x186e5c){if(!_0x186e5c?.['filename'])throw TypeError('SQLiteHistoryDatabaseAdapter\x20requires\x20a\x20filename');if(_0x186e5c['busyTimeoutMs']!==void 0x0&&(!Number['isSafeInteger'](_0x186e5c['busyTimeoutMs'])||_0x186e5c['busyTimeoutMs']<0x0))throw TypeError('busyTimeoutMs\x20must\x20be\x20a\x20non-negative\x20safe\x20integer');}function _(_0x453eb3){return Error(_0x453eb3);}function v(_0x4bcc3a){if(!_0x4bcc3a['unitID']||!_0x4bcc3a['userID']||!Number['isSafeInteger'](_0x4bcc3a['revision'])||_0x4bcc3a['revision']<0x1||!Number['isSafeInteger'](_0x4bcc3a['historyRevision'])||_0x4bcc3a['historyRevision']<0x1||_0x4bcc3a['historyRevision']>_0x4bcc3a['revision']||!Number['isSafeInteger'](_0x4bcc3a['committedAt'])||_0x4bcc3a['committedAt']<0x0)throw TypeError('History\x20revision\x20entry\x20is\x20invalid');}exports['SQLiteHistoryDatabaseAdapter']=m;
1
+ Object['defineProperty'](exports,Symbol['toStringTag'],{'value':'Module'});var e=Object['create'],t=Object['defineProperty'],n=Object['getOwnPropertyDescriptor'],r=Object['getOwnPropertyNames'],i=Object['getPrototypeOf'],a=Object['prototype']['hasOwnProperty'],o=(_0x531197,_0x3b6132,_0x25cc0b,_0x5f049e)=>{if(_0x3b6132&&typeof _0x3b6132=='object'||typeof _0x3b6132=='function'){for(var _0x59f9ac=r(_0x3b6132),_0x6d33eb=0x0,_0x2c86bf=_0x59f9ac['length'],_0x1d69e9;_0x6d33eb<_0x2c86bf;_0x6d33eb++)_0x1d69e9=_0x59f9ac[_0x6d33eb],!a['call'](_0x531197,_0x1d69e9)&&_0x1d69e9!==_0x25cc0b&&t(_0x531197,_0x1d69e9,{'get':(_0x291bb3=>_0x3b6132[_0x291bb3])['bind'](null,_0x1d69e9),'enumerable':!(_0x5f049e=n(_0x3b6132,_0x1d69e9))||_0x5f049e['enumerable']});}return _0x531197;},s=(_0xb5731e,_0x310df2,_0x52d0e5)=>(_0x52d0e5=_0xb5731e==null?{}:e(i(_0xb5731e)),o(_0x310df2||!_0xb5731e||!_0xb5731e['__esModule']?t(_0x52d0e5,'default',{'value':_0xb5731e,'enumerable':!0x0}):_0x52d0e5,_0xb5731e));let c=require('libsql');c=s(c,0x1);var l='\x0a\x20\x20CREATE\x20TABLE\x20collaboration_history_records\x20(\x0a\x20\x20\x20\x20unit_id\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20start_revision\x20INTEGER\x20NOT\x20NULL\x20CHECK\x20(start_revision\x20>=\x201),\x0a\x20\x20\x20\x20user_id\x20TEXT\x20NOT\x20NULL,\x0a\x20\x20\x20\x20created_at_ms\x20INTEGER\x20NOT\x20NULL\x20CHECK\x20(created_at_ms\x20>=\x200),\x0a\x20\x20\x20\x20origin\x20INTEGER\x20NOT\x20NULL,\x0a\x20\x20\x20\x20additional_fields\x20TEXT,\x0a\x20\x20\x20\x20PRIMARY\x20KEY\x20(unit_id,\x20start_revision)\x0a\x20\x20);\x0a',u='\x0a\x20\x20CREATE\x20INDEX\x20collaboration_history_origin_lookup\x0a\x20\x20\x20\x20ON\x20collaboration_history_records(unit_id,\x20origin,\x20start_revision);\x0a\x20\x20CREATE\x20INDEX\x20collaboration_history_creator_lookup\x0a\x20\x20\x20\x20ON\x20collaboration_history_records(unit_id,\x20user_id,\x20start_revision);\x0a',d=class{['_database'];['_disposed']=!0x1;constructor(_0x2c7774){if(!_0x2c7774?.['filename'])throw TypeError('SQLiteHistoryDatabaseAdapter\x20requires\x20a\x20filename');let _0x386edd=_0x2c7774['busyTimeoutMs']??0x1388;if(!Number['isSafeInteger'](_0x386edd)||_0x386edd<0x0)throw TypeError('busyTimeoutMs\x20must\x20be\x20a\x20non-negative\x20safe\x20integer');this['_database']=new c['default'](_0x2c7774['filename'],{'timeout':_0x386edd});try{this['_database']['exec']('PRAGMA\x20busy_timeout\x20=\x20'+_0x386edd+';'),this['_initializeSchema']();}catch(_0x18b662){throw this['_database']['close'](),_0x18b662;}}async['getLatestRecord'](_0x3ea739,_0x4e344b){this['_assertOpen']();let _0x47e446=this['_latest'](_0x4e344b);return _0x47e446?f(_0x47e446):null;}async['appendRecord'](_0x3b11bb,_0x27f5b4,_0x3d1c99){if(this['_assertOpen'](),!_0x27f5b4['unitID']||!_0x27f5b4['userID']||!Number['isSafeInteger'](_0x27f5b4['startRevision'])||_0x27f5b4['startRevision']<0x1||!Number['isSafeInteger'](_0x27f5b4['createdAt'])||_0x27f5b4['createdAt']<0x0)throw TypeError('History\x20record\x20is\x20invalid');return this['_transaction'](()=>{let _0x134ff5=this['_database']['prepare']('SELECT\x20*\x20FROM\x20collaboration_history_records\x0a\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20unit_id\x20=\x20?\x20AND\x20start_revision\x20=\x20?')['get'](_0x27f5b4['unitID'],_0x27f5b4['startRevision']);if(_0x134ff5)return{'status':_0x134ff5['user_id']===_0x27f5b4['userID']&&_0x134ff5['created_at_ms']===_0x27f5b4['createdAt']&&_0x134ff5['origin']===_0x27f5b4['origin']&&_0x134ff5['additional_fields']===(_0x27f5b4['additionalFields']??null)?'already-exists':'conflict'};let _0x16aa78=this['_latest'](_0x27f5b4['unitID'])?.['start_revision']??null;return _0x16aa78!==_0x3d1c99['expectedLatestStartRevision']||_0x27f5b4['startRevision']<=(_0x16aa78??0x0)?{'status':'conflict'}:(this['_database']['prepare']('INSERT\x20INTO\x20collaboration_history_records\x0a\x20\x20\x20\x20\x20\x20\x20\x20(unit_id,\x20start_revision,\x20user_id,\x20created_at_ms,\x20origin,\x20additional_fields)\x0a\x20\x20\x20\x20\x20\x20\x20\x20VALUES\x20(?,\x20?,\x20?,\x20?,\x20?,\x20?)')['run'](_0x27f5b4['unitID'],_0x27f5b4['startRevision'],_0x27f5b4['userID'],_0x27f5b4['createdAt'],_0x27f5b4['origin'],_0x27f5b4['additionalFields']??null),{'status':'appended'});});}async['listRecords'](_0x3e9227,_0xb89887,_0x27eb93){this['_assertOpen']();let _0x158529=[_0x27eb93['throughRevision'],_0x27eb93['throughRevision'],_0xb89887,_0x27eb93['throughRevision']],_0x3297ab=[];_0x27eb93['beforeRevision']!==void 0x0&&(_0x3297ab['push']('r.start_revision\x20<\x20?'),_0x158529['push'](_0x27eb93['beforeRevision'])),_0x27eb93['origin']&&(_0x3297ab['push']('r.origin\x20=\x20?'),_0x158529['push'](_0x27eb93['origin'])),_0x27eb93['userIDs']?.['length']&&(_0x3297ab['push']('r.user_id\x20IN\x20('+_0x27eb93['userIDs']['map'](()=>'?')['join'](',\x20')+')'),_0x158529['push'](..._0x27eb93['userIDs'])),_0x158529['push'](_0x27eb93['length']+0x1);let _0x2cd9a4=this['_database']['prepare']('\x0a\x20\x20\x20\x20\x20\x20SELECT\x20r.*,\x20MIN(?,\x20COALESCE((\x0a\x20\x20\x20\x20\x20\x20\x20\x20SELECT\x20next.start_revision\x20-\x201\x20FROM\x20collaboration_history_records\x20AS\x20next\x0a\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20next.unit_id\x20=\x20r.unit_id\x20AND\x20next.start_revision\x20>\x20r.start_revision\x0a\x20\x20\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20next.start_revision\x20ASC\x20LIMIT\x201\x0a\x20\x20\x20\x20\x20\x20),\x20?))\x20AS\x20end_revision\x0a\x20\x20\x20\x20\x20\x20FROM\x20collaboration_history_records\x20AS\x20r\x0a\x20\x20\x20\x20\x20\x20WHERE\x20r.unit_id\x20=\x20?\x20AND\x20r.start_revision\x20<=\x20?\x0a\x20\x20\x20\x20\x20\x20\x20\x20'+(_0x3297ab['length']?'AND\x20'+_0x3297ab['join']('\x20AND\x20'):'')+'\x0a\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20r.start_revision\x20DESC\x20LIMIT\x20?\x0a\x20\x20\x20\x20')['all'](..._0x158529);return{'records':_0x2cd9a4['slice'](0x0,_0x27eb93['length'])['map'](_0x8727f1=>({'record':f(_0x8727f1),'endRevision':_0x8727f1['end_revision']})),'hasMore':_0x2cd9a4['length']>_0x27eb93['length']};}async['listCreators'](_0x348c9c,_0x5baacc,_0x3c9df4){this['_assertOpen']();let _0x4a9a80=this['_database']['prepare']('SELECT\x20DISTINCT\x20user_id,\x20origin\x20FROM\x20collaboration_history_records\x0a\x20\x20\x20\x20\x20\x20WHERE\x20unit_id\x20=\x20?\x20AND\x20start_revision\x20<=\x20?\x20ORDER\x20BY\x20user_id,\x20origin')['all'](_0x5baacc,_0x3c9df4['throughRevision']),_0x3ad981=new Map();for(let _0xdde9db of _0x4a9a80){let _0x41aae0=_0x3ad981['get'](_0xdde9db['user_id'])??[];_0x41aae0['push'](_0xdde9db['origin']),_0x3ad981['set'](_0xdde9db['user_id'],_0x41aae0);}return[..._0x3ad981]['map'](([_0x2e5d40,_0x2e0aa9])=>({'userID':_0x2e5d40,'origins':_0x2e0aa9}));}async['dispose'](){this['_disposed']||(this['_disposed']=!0x0,this['_database']['close']());}['_latest'](_0x42860c){return this['_database']['prepare']('SELECT\x20*\x20FROM\x20collaboration_history_records\x0a\x20\x20\x20\x20\x20\x20WHERE\x20unit_id\x20=\x20?\x20ORDER\x20BY\x20start_revision\x20DESC\x20LIMIT\x201')['get'](_0x42860c);}['_initializeSchema'](){this['_transaction'](()=>{let _0x1ba5c5=_0x41af74=>!!this['_database']['prepare']('SELECT\x201\x20FROM\x20sqlite_schema\x20WHERE\x20type\x20=\x20\x27table\x27\x20AND\x20name\x20=\x20?')['get'](_0x41af74),_0x364d1d=_0x1ba5c5('collaboration_history_revisions')||_0x1ba5c5('collaboration_history_records');if(!_0x1ba5c5('collaboration_schema_versions')){if(_0x364d1d)throw Error('SQLite\x20History\x20tables\x20exist\x20without\x20a\x20schema\x20version');this['_database']['exec']('CREATE\x20TABLE\x20collaboration_schema_versions\x20(\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20component\x20TEXT\x20PRIMARY\x20KEY,\x20version\x20INTEGER\x20NOT\x20NULL\x20CHECK\x20(version\x20>=\x201));');}let _0x6b757d=this['_database']['prepare']('SELECT\x20version\x20FROM\x20collaboration_schema_versions\x20WHERE\x20component\x20=\x20\x27history\x27')['get']();if(_0x6b757d){if(_0x6b757d['version']===0x1)throw Error('SQLite\x20History\x20schema\x20v1\x20requires\x20migrateSQLiteHistoryV1ToV2\x20before\x20opening\x20the\x20Adapter');if(_0x6b757d['version']!==0x2)throw Error('SQLite\x20History\x20schema\x20version\x20'+_0x6b757d['version']+'\x20is\x20not\x20supported');if(!_0x1ba5c5('collaboration_history_records'))throw Error('SQLite\x20History\x20schema\x20v2\x20is\x20incomplete');this['_database']['prepare']('SELECT\x20unit_id,\x20start_revision,\x20user_id,\x20created_at_ms,\x20origin,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20additional_fields\x20FROM\x20collaboration_history_records\x20LIMIT\x200')['all']();return;}if(_0x364d1d)throw Error('SQLite\x20History\x20tables\x20exist\x20without\x20a\x20schema\x20version');this['_database']['exec'](l+u+'INSERT\x20INTO\x20collaboration_schema_versions\x20(component,\x20version)\x20VALUES\x20(\x27history\x27,\x202);');});}['_transaction'](_0x3592b3){this['_database']['exec']('BEGIN\x20IMMEDIATE;');try{let _0x196686=_0x3592b3();return this['_database']['exec']('COMMIT;'),_0x196686;}catch(_0x24f11c){throw this['_database']['exec']('ROLLBACK;'),_0x24f11c;}}['_assertOpen'](){if(this['_disposed'])throw Error('SQLite\x20History\x20Database\x20Adapter\x20is\x20disposed');}};function f(_0x348afd){return{'unitID':_0x348afd['unit_id'],'startRevision':_0x348afd['start_revision'],'userID':_0x348afd['user_id'],'createdAt':_0x348afd['created_at_ms'],'origin':_0x348afd['origin'],..._0x348afd['additional_fields']===null?{}:{'additionalFields':_0x348afd['additional_fields']}};}async function p(_0x432a50){let _0x4f8747=new c['default'](_0x432a50['filename'],{'fileMustExist':!0x0}),_0x149ab7=!0x1;try{if(_0x4f8747['exec']('BEGIN\x20IMMEDIATE;'),_0x149ab7=!0x0,_0x4f8747['prepare']('SELECT\x20version\x20FROM\x20collaboration_schema_versions\x20WHERE\x20component\x20=\x20\x27history\x27')['get']()?.['version']!==0x1)throw Error('History\x20v1-to-v2\x20migration\x20requires\x20schema\x20version\x201');if(_0x4f8747['prepare']('SELECT\x20version\x20FROM\x20collaboration_schema_versions\x20WHERE\x20component\x20=\x20\x27core\x27')['get']()?.['version']===0x1)throw Error('Migrate\x20SQLite\x20Core\x20v1\x20before\x20History\x20so\x20creation\x20facts\x20remain\x20available');let _0x24b989=_0x4f8747['prepare']('SELECT\x20version\x20FROM\x20collaboration_schema_versions\x20WHERE\x20component\x20=\x20\x27worktree\x27')['get']();if(_0x24b989&&_0x24b989['version']<0x3)throw Error('Migrate\x20SQLite\x20Worktree\x20before\x20History\x20so\x20creation\x20facts\x20remain\x20available');if(_0x4f8747['prepare']('SELECT\x201\x20FROM\x20collaboration_history_revisions\x20AS\x20r\x0a\x20\x20\x20\x20\x20\x20LEFT\x20JOIN\x20collaboration_history_revisions\x20AS\x20first\x0a\x20\x20\x20\x20\x20\x20\x20\x20ON\x20first.unit_id\x20=\x20r.unit_id\x20AND\x20first.revision\x20=\x20r.history_revision\x0a\x20\x20\x20\x20\x20\x20WHERE\x20r.history_revision\x20>\x20r.revision\x20OR\x20first.revision\x20IS\x20NULL\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20OR\x20first.history_revision\x20!=\x20first.revision\x20OR\x20first.user_id\x20=\x20\x27\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20OR\x20typeof(first.committed_at)\x20!=\x20\x27integer\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20OR\x20first.committed_at\x20<\x200\x20OR\x20first.committed_at\x20>\x209007199254740991\x0a\x20\x20\x20\x20\x20\x20LIMIT\x201')['get']())throw Error('History\x20v1\x20contains\x20a\x20missing\x20or\x20invalid\x20segment\x20starting\x20revision');_0x4f8747['exec'](l),_0x4f8747['exec']('INSERT\x20INTO\x20collaboration_history_records\x0a\x20\x20\x20\x20\x20\x20(unit_id,\x20start_revision,\x20user_id,\x20created_at_ms,\x20origin,\x20additional_fields)\x0a\x20\x20\x20\x20\x20\x20SELECT\x20unit_id,\x20revision,\x20user_id,\x20committed_at,\x20origin,\x20additional_fields\x0a\x20\x20\x20\x20\x20\x20FROM\x20collaboration_history_revisions\x20WHERE\x20revision\x20=\x20history_revision;\x0a\x20\x20\x20\x20\x20\x20DROP\x20TABLE\x20collaboration_history_revisions;'),_0x4f8747['exec'](u),_0x4f8747['exec']('UPDATE\x20collaboration_schema_versions\x20SET\x20version\x20=\x202\x20WHERE\x20component\x20=\x20\x27history\x27;\x20COMMIT;'),_0x149ab7=!0x1;}finally{try{_0x149ab7&&_0x4f8747['exec']('ROLLBACK;');}finally{_0x4f8747['close']();}}}exports['SQLiteHistoryDatabaseAdapter']=d,exports['migrateSQLiteHistoryV1ToV2']=p;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AppendHistoryRevisionResult, HistoryCreatorIndex, HistoryIndexState, HistoryRevision, IHistoryDatabaseAdapter, ListHistoryRecordsOptions, ListHistoryRecordsResult } from "@univerjs-pro/collaboration-history-service";
1
+ import { AppendHistoryRecordResult, HistoryCreatorIndex, HistoryDatabaseContext, HistoryRecord, IHistoryDatabaseAdapter, ListHistoryRecordsOptions, ListHistoryRecordsResult } from "@univerjs-pro/collaboration-history-service";
2
2
 
3
3
  //#region src/sqlite-history-database-adapter.d.ts
4
4
  interface SQLiteHistoryDatabaseAdapterOptions {
@@ -9,21 +9,25 @@ declare class SQLiteHistoryDatabaseAdapter implements IHistoryDatabaseAdapter {
9
9
  private readonly _database;
10
10
  private _disposed;
11
11
  constructor(options: SQLiteHistoryDatabaseAdapterOptions);
12
- getIndexState(unitID: string): Promise<HistoryIndexState | null>;
13
- getRevision(unitID: string, revision: number): Promise<HistoryRevision | null>;
14
- appendRevision(entry: HistoryRevision, options: {
15
- readonly expectedLatestRevision: number;
16
- }): Promise<AppendHistoryRevisionResult>;
17
- listRecords(unitID: string, options: ListHistoryRecordsOptions): Promise<ListHistoryRecordsResult>;
18
- listCreators(unitID: string): Promise<readonly HistoryCreatorIndex[]>;
12
+ getLatestRecord(_context: HistoryDatabaseContext, unitID: string): Promise<HistoryRecord | null>;
13
+ appendRecord(_context: HistoryDatabaseContext, record: HistoryRecord, options: {
14
+ readonly expectedLatestStartRevision: number | null;
15
+ }): Promise<AppendHistoryRecordResult>;
16
+ listRecords(_context: HistoryDatabaseContext, unitID: string, options: ListHistoryRecordsOptions): Promise<ListHistoryRecordsResult>;
17
+ listCreators(_context: HistoryDatabaseContext, unitID: string, options: {
18
+ readonly throughRevision: number;
19
+ }): Promise<readonly HistoryCreatorIndex[]>;
19
20
  dispose(): Promise<void>;
21
+ private _latest;
20
22
  private _initializeSchema;
21
- private _hasTable;
22
- private _hasAnyOwnedTable;
23
- private _latestEntry;
24
- private _getEntry;
25
23
  private _transaction;
26
24
  private _assertOpen;
27
25
  }
28
26
  //#endregion
29
- export { SQLiteHistoryDatabaseAdapter, type SQLiteHistoryDatabaseAdapterOptions };
27
+ //#region src/migrations/v1-to-v2.d.ts
28
+ interface SQLiteHistoryV1ToV2MigrationOptions {
29
+ readonly filename: string;
30
+ }
31
+ declare function migrateSQLiteHistoryV1ToV2(options: SQLiteHistoryV1ToV2MigrationOptions): Promise<void>;
32
+ //#endregion
33
+ export { SQLiteHistoryDatabaseAdapter, type SQLiteHistoryDatabaseAdapterOptions, type SQLiteHistoryV1ToV2MigrationOptions, migrateSQLiteHistoryV1ToV2 };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- const _0x10d45c=_0x5365;(function(_0x5aadb9,_0x3d647f){const _0x38c8a5=_0x5365,_0x26574c=_0x5aadb9();while(!![]){try{const _0x50e403=-parseInt(_0x38c8a5(0x160))/0x1*(parseInt(_0x38c8a5(0x162))/0x2)+parseInt(_0x38c8a5(0x15a))/0x3*(parseInt(_0x38c8a5(0x158))/0x4)+parseInt(_0x38c8a5(0x15c))/0x5*(-parseInt(_0x38c8a5(0x15d))/0x6)+-parseInt(_0x38c8a5(0x159))/0x7*(parseInt(_0x38c8a5(0x15f))/0x8)+-parseInt(_0x38c8a5(0x161))/0x9+-parseInt(_0x38c8a5(0x164))/0xa*(-parseInt(_0x38c8a5(0x165))/0xb)+parseInt(_0x38c8a5(0x15e))/0xc*(parseInt(_0x38c8a5(0x15b))/0xd);if(_0x50e403===_0x3d647f)break;else _0x26574c['push'](_0x26574c['shift']());}catch(_0x2ca2cc){_0x26574c['push'](_0x26574c['shift']());}}}(_0x2eeb,0xd367b));import _0x247c83 from'./index.cjs';const facadeExport0=_0x247c83[_0x10d45c(0x163)];function _0x2eeb(){const _0x14007e=['6kFpwIx','375606oEHtyE','161114dNhJrZ','SQLiteHistoryDatabaseAdapter','10jOpTDf','10725099sBftTN','4RtdOJZ','385aPbWEC','1283733HltVvO','1477346oEMBwX','4333960yBuYnc','6hWrjqI','108mYUzlG','24424IeOwzS'];_0x2eeb=function(){return _0x14007e;};return _0x2eeb();}function _0x5365(_0x268b9d,_0x3f85c7){_0x268b9d=_0x268b9d-0x158;const _0x2eebfd=_0x2eeb();let _0x53654c=_0x2eebfd[_0x268b9d];return _0x53654c;}export{facadeExport0 as SQLiteHistoryDatabaseAdapter};
1
+ const _0x20a153=_0x2eae;(function(_0x237ff4,_0x43f6b3){const _0x13a343=_0x2eae,_0x1ef63b=_0x237ff4();while(!![]){try{const _0x4a785f=parseInt(_0x13a343(0x100))/0x1+-parseInt(_0x13a343(0xfd))/0x2+-parseInt(_0x13a343(0x102))/0x3*(parseInt(_0x13a343(0xfb))/0x4)+parseInt(_0x13a343(0x103))/0x5+parseInt(_0x13a343(0xfe))/0x6+parseInt(_0x13a343(0x101))/0x7*(parseInt(_0x13a343(0xf9))/0x8)+-parseInt(_0x13a343(0xff))/0x9;if(_0x4a785f===_0x43f6b3)break;else _0x1ef63b['push'](_0x1ef63b['shift']());}catch(_0x2f6792){_0x1ef63b['push'](_0x1ef63b['shift']());}}}(_0x4245,0xb4fbf));import _0x2d5dc3 from'./index.cjs';function _0x2eae(_0x20b176,_0x12254a){_0x20b176=_0x20b176-0xf9;const _0x424576=_0x4245();let _0x2eae37=_0x424576[_0x20b176];return _0x2eae37;}function _0x4245(){const _0x4c6231=['3078018YhdqJC','17956116fMpOOS','938630uoVxHb','12292QhSyLh','390501amuypa','7069145QbJwxp','2952UdlexJ','SQLiteHistoryDatabaseAdapter','12JbLEsy','migrateSQLiteHistoryV1ToV2','772980GyjBNB'];_0x4245=function(){return _0x4c6231;};return _0x4245();}const facadeExport0=_0x2d5dc3[_0x20a153(0xfa)],facadeExport1=_0x2d5dc3[_0x20a153(0xfc)];export{facadeExport0 as SQLiteHistoryDatabaseAdapter,facadeExport1 as migrateSQLiteHistoryV1ToV2};
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "engines": {
5
5
  "node": ">=22"
6
6
  },
7
- "version": "1.0.0-rc.0",
7
+ "version": "1.0.1",
8
8
  "main": "./dist/index.cjs",
9
9
  "module": "./dist/index.mjs",
10
10
  "types": "./dist/index.d.ts",
@@ -19,8 +19,8 @@
19
19
  "dist"
20
20
  ],
21
21
  "dependencies": {
22
- "@univerjs-pro/collaboration-history-service": "1.0.0-rc.0",
23
- "@univerjs/protocol": "1.0.0-rc.0",
22
+ "@univerjs-pro/collaboration-history-service": "1.0.1",
23
+ "@univerjs/protocol": "1.0.1",
24
24
  "libsql": "^0.5.29"
25
25
  }
26
26
  }