@univerjs-pro/collaboration-worktree-endpoint 1.0.0-insiders.20260808-70eefdd → 1.0.0
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 +104 -0
- package/README.zh-CN.md +111 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +11 -14
- package/dist/index.mjs +1 -1
- package/package.json +7 -10
package/README.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# @univerjs-pro/collaboration-worktree-endpoint
|
|
2
|
+
|
|
3
|
+
English | [简体中文](./README.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
Provides Worktree management APIs and accepts Univer collaboration requests scoped to a specific Worktree. It uses `UniverCollabWorktreeService` APIs for Worktree management and collaboration-data operations.
|
|
6
|
+
|
|
7
|
+
## Installation and registration
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add \
|
|
11
|
+
@univerjs-pro/collaboration-worktree-service \
|
|
12
|
+
@univerjs-pro/collaboration-worktree-endpoint \
|
|
13
|
+
@univerjs-pro/collaboration-endpoint \
|
|
14
|
+
@univerjs-pro/collaboration-transport-node
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Worktree Endpoint and trunk Endpoint must share the same `ticketStore`:
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
const ticketStore = new MemorySessionTicketStore();
|
|
21
|
+
const trunkEndpoint = new UniverCollabEndpoint(collabService, { ticketStore });
|
|
22
|
+
const worktreeEndpoint = new UniverCollabWorktreeEndpoint(
|
|
23
|
+
worktreeService,
|
|
24
|
+
{ ticketStore }
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
transport.use(authenticationMiddleware);
|
|
28
|
+
transport.register(trunkEndpoint);
|
|
29
|
+
transport.register(worktreeEndpoint);
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Authentication middleware must first set `ctx.userID` for HTTP requests. Apart from sharing the same `ticketStore` instance, no extra association between Endpoints is needed. Every WebSocket connection still uses its own one-time ticket.
|
|
33
|
+
|
|
34
|
+
## What the frontend receives
|
|
35
|
+
|
|
36
|
+
- Worktree HTTP APIs for create, read, ready, reopen, discard, merge, and preview.
|
|
37
|
+
- Separate snapshot, changeset, ACK, broadcast, and Presence channels for each Worktree.
|
|
38
|
+
- A `/events` WebSocket for Worktree state changes, allowing product UI to refresh ready/merged state.
|
|
39
|
+
|
|
40
|
+
Applications do not place `worktreeID` into changesets or room IDs themselves. The browser configures the target Worktree, Endpoint reads `worktreeID` from the URL, and data and realtime rooms remain isolated between Worktrees.
|
|
41
|
+
|
|
42
|
+
## Worktree protocol paths
|
|
43
|
+
|
|
44
|
+
The protocol is rooted at `/universer-api/worktrees/:worktreeID`. One collaboration WebSocket belongs to one Worktree. Even with the same `unitID`, edits and online members in different Worktrees are isolated. Worktree state changes use a separate `/events` WebSocket instead of injecting unknown events into the collaboration WebSocket.
|
|
45
|
+
|
|
46
|
+
Management APIs:
|
|
47
|
+
|
|
48
|
+
| Method | Path | Purpose |
|
|
49
|
+
| --- | --- | --- |
|
|
50
|
+
| `POST` | `/universer-api/worktrees` | Create Worktree |
|
|
51
|
+
| `GET` | `/universer-api/worktrees/:worktreeID` | Read complete Worktree state |
|
|
52
|
+
| `POST` | `/universer-api/worktrees/:worktreeID/units` | Add an existing trunk Unit |
|
|
53
|
+
| `POST` | `/universer-api/worktrees/:worktreeID/units/from-snapshot` | Create draft Unit from protocol snapshot |
|
|
54
|
+
| `POST` | `/universer-api/worktrees/:worktreeID/units/from-data` | Create draft Unit from Univer Unit data |
|
|
55
|
+
| `GET` | `/universer-api/worktrees/:worktreeID/units/:unitID/merge-preview` | Evaluate one Unit merge |
|
|
56
|
+
| `POST` | `/universer-api/worktrees/:worktreeID/ready` | Freeze each Unit's current draft revision |
|
|
57
|
+
| `POST` | `/universer-api/worktrees/:worktreeID/reopen` | Return to draft |
|
|
58
|
+
| `POST` | `/universer-api/worktrees/:worktreeID/merge` | Merge Units into trunk one by one |
|
|
59
|
+
| `POST` | `/universer-api/worktrees/:worktreeID/discard` | Discard Worktree |
|
|
60
|
+
|
|
61
|
+
Realtime and collaboration channels:
|
|
62
|
+
|
|
63
|
+
| Channel | Path | Purpose |
|
|
64
|
+
| --- | --- | --- |
|
|
65
|
+
| HTTP | `/universer-api/worktrees/:worktreeID/snapshot/...` | Read this Worktree's snapshot, blocks, and missing changesets |
|
|
66
|
+
| HTTP | `/universer-api/worktrees/:worktreeID/comb/...` | Submit a changeset to this Worktree |
|
|
67
|
+
| WebSocket | `/universer-api/worktrees/:worktreeID/comb/connect` | Worktree Sessions, rooms, Presence, ACKs, broadcasts |
|
|
68
|
+
| WebSocket | `/universer-api/worktrees/:worktreeID/events` | Push complete `WorktreeData` state |
|
|
69
|
+
|
|
70
|
+
The URL is authoritative for `worktreeID`. `merge-preview` evaluates one Unit only in `ready`, uses `Cache-Control: no-store`, and does not perform a formal merge.
|
|
71
|
+
|
|
72
|
+
## Middleware
|
|
73
|
+
|
|
74
|
+
Worktree Endpoint middleware controls only the current Worktree's Sessions and realtime rooms:
|
|
75
|
+
|
|
76
|
+
| Action | When it runs | Visible fields | Retry semantics | Typical uses |
|
|
77
|
+
| --- | --- | --- | --- | --- |
|
|
78
|
+
| `connect` | After consuming ticket and creating Worktree Session, before registering collaboration or `/events` connection | `worktreeID`, `session`, `connection`, `member` | Once per connection; reconnect runs again | Member display, connection policy |
|
|
79
|
+
| `joinUnit` | After `JOIN`, before Session joins current Worktree room | `worktreeID`, `session`, `unitID` | Once for Session's first JOIN; Endpoint does not retry | Worktree and Unit read ACL |
|
|
80
|
+
| `receivePresence` | After joined Session sends Presence, before room broadcast | `worktreeID`, `session`, `unitID`, `payload`, event-scoped `customData` | Once per Presence; Endpoint does not retry | Validation, rate limits, filtering |
|
|
81
|
+
| `sendPresence` | Before sending Presence to one current-Worktree room member | `worktreeID`, `session`, `unitID`, `payload`, event-scoped `customData`, `targetMemberID` | Once per target; send failure not retried | Per-recipient display-data filtering |
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
worktreeEndpoint.use('joinUnit', async (ctx, next) => {
|
|
85
|
+
if (!await acl.canReadWorktreeUnit(
|
|
86
|
+
ctx.session.userID,
|
|
87
|
+
ctx.worktreeID,
|
|
88
|
+
ctx.unitID
|
|
89
|
+
)) {
|
|
90
|
+
throw new CollabError('PERMISSION_DENIED', 'Cannot join this Worktree Unit');
|
|
91
|
+
}
|
|
92
|
+
await next();
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
`joinUnit` protects only realtime rooms. Worktree data reads, submissions, and merge must be protected by Worktree Service middleware. Service middleware receives `ctx.userID/customData` attached to the current HTTP request by Transport.
|
|
97
|
+
|
|
98
|
+
## Deployment and disposal
|
|
99
|
+
|
|
100
|
+
Realtime rooms, state events, and broadcasts are currently guaranteed only within one Endpoint process.
|
|
101
|
+
|
|
102
|
+
Transport disposes registered Endpoints. Endpoint does not dispose Worktree Service, trunk Service, or the application-provided `ticketStore`.
|
|
103
|
+
|
|
104
|
+
`POST /universer-api/worktrees/:worktreeID/units/:unitID/removal` accepts `{ "removed": true }` or `{ "removed": false }`. The authenticated call delegates to `setUnitRemoved` and returns the updated Worktree. Removal events also update Worktree subscribers.
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# @univerjs-pro/collaboration-worktree-endpoint
|
|
2
|
+
|
|
3
|
+
[English](./README.md) | [简体中文](./README.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
提供 Worktree 管理 API,并接收限定到具体 Worktree 的 Univer 协同请求。它使用
|
|
6
|
+
`UniverCollabWorktreeService` API 处理 Worktree 管理和协同数据操作。
|
|
7
|
+
|
|
8
|
+
## 安装与注册
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
pnpm add \
|
|
12
|
+
@univerjs-pro/collaboration-worktree-service \
|
|
13
|
+
@univerjs-pro/collaboration-worktree-endpoint \
|
|
14
|
+
@univerjs-pro/collaboration-endpoint \
|
|
15
|
+
@univerjs-pro/collaboration-transport-node
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Worktree Endpoint 和 trunk Endpoint 需要共享同一个 `ticketStore`:
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
const ticketStore = new MemorySessionTicketStore();
|
|
22
|
+
const trunkEndpoint = new UniverCollabEndpoint(collabService, { ticketStore });
|
|
23
|
+
const worktreeEndpoint = new UniverCollabWorktreeEndpoint(
|
|
24
|
+
worktreeService,
|
|
25
|
+
{ ticketStore }
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
transport.use(authenticationMiddleware);
|
|
29
|
+
transport.register(trunkEndpoint);
|
|
30
|
+
transport.register(worktreeEndpoint);
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
认证 middleware 必须先为 HTTP 请求设置 `ctx.userID`。除共享同一个 `ticketStore` 实例外,
|
|
34
|
+
无需额外关联两个 Endpoint;每条 WebSocket 连接仍使用独立的一次性 ticket。
|
|
35
|
+
|
|
36
|
+
## 前端会获得什么
|
|
37
|
+
|
|
38
|
+
- 一组用于创建、读取、ready、reopen、discard、merge 和预览的 Worktree HTTP API。
|
|
39
|
+
- 每个 Worktree 独立的 snapshot、changeset、ACK、广播和 Presence 通道。
|
|
40
|
+
- Worktree 状态变化的 `/events` WebSocket,便于产品 UI 刷新 ready/merged 等状态。
|
|
41
|
+
|
|
42
|
+
应用不需要自己把 `worktreeID` 塞进 changeset 或 room ID。浏览器只配置目标 Worktree,
|
|
43
|
+
Endpoint 从 URL 取得 `worktreeID` 并保持不同 Worktree 之间的数据和实时房间隔离。
|
|
44
|
+
|
|
45
|
+
## Worktree 协议路径
|
|
46
|
+
|
|
47
|
+
协议位于 `/universer-api/worktrees/:worktreeID`。一条协同 WebSocket 只属于一个
|
|
48
|
+
Worktree;即使 `unitID` 相同,不同 Worktree 的编辑和在线成员也彼此隔离。Worktree 状态
|
|
49
|
+
变化通过独立 `/events` WebSocket 发送,不向协同 WebSocket 注入未知事件。
|
|
50
|
+
|
|
51
|
+
管理 API:
|
|
52
|
+
|
|
53
|
+
| Method | Path | 用途 |
|
|
54
|
+
| --- | --- | --- |
|
|
55
|
+
| `POST` | `/universer-api/worktrees` | 创建 Worktree |
|
|
56
|
+
| `GET` | `/universer-api/worktrees/:worktreeID` | 读取完整 Worktree 状态 |
|
|
57
|
+
| `POST` | `/universer-api/worktrees/:worktreeID/units` | 加入已有 trunk Unit |
|
|
58
|
+
| `POST` | `/universer-api/worktrees/:worktreeID/units/from-snapshot` | 从 protocol snapshot 创建 draft Unit |
|
|
59
|
+
| `POST` | `/universer-api/worktrees/:worktreeID/units/from-data` | 从 Univer Unit data 创建 draft Unit |
|
|
60
|
+
| `GET` | `/universer-api/worktrees/:worktreeID/units/:unitID/merge-preview` | 评估单 Unit 合入 |
|
|
61
|
+
| `POST` | `/universer-api/worktrees/:worktreeID/ready` | 冻结各 Unit 当前的 draft revision |
|
|
62
|
+
| `POST` | `/universer-api/worktrees/:worktreeID/reopen` | 重新进入 draft |
|
|
63
|
+
| `POST` | `/universer-api/worktrees/:worktreeID/merge` | 逐 Unit 合入 trunk |
|
|
64
|
+
| `POST` | `/universer-api/worktrees/:worktreeID/discard` | 丢弃 Worktree |
|
|
65
|
+
|
|
66
|
+
实时和协同通道:
|
|
67
|
+
|
|
68
|
+
| 通道 | Path | 用途 |
|
|
69
|
+
| --- | --- | --- |
|
|
70
|
+
| HTTP | `/universer-api/worktrees/:worktreeID/snapshot/...` | 读取该 Worktree 的 snapshot、blocks 和缺失 changesets |
|
|
71
|
+
| HTTP | `/universer-api/worktrees/:worktreeID/comb/...` | 向该 Worktree 提交 changeset |
|
|
72
|
+
| WebSocket | `/universer-api/worktrees/:worktreeID/comb/connect` | 该 Worktree 的 Session、房间、Presence、ACK 和广播 |
|
|
73
|
+
| WebSocket | `/universer-api/worktrees/:worktreeID/events` | 推送完整 `WorktreeData` 状态 |
|
|
74
|
+
|
|
75
|
+
URL 是 `worktreeID` 的权威来源。`merge-preview` 只在 `ready` 状态评估一个 Unit,使用
|
|
76
|
+
`Cache-Control: no-store`,不执行正式 merge。
|
|
77
|
+
|
|
78
|
+
## Middleware
|
|
79
|
+
|
|
80
|
+
Worktree Endpoint middleware 只控制当前 Worktree 的 Session 和实时房间:
|
|
81
|
+
|
|
82
|
+
| Action | 触发时机 | 可见字段 | 重试语义 | 典型用途 |
|
|
83
|
+
| --- | --- | --- | --- | --- |
|
|
84
|
+
| `connect` | ticket 已消费并创建 Worktree Session,注册协同或 `/events` 连接前 | `worktreeID`、`session`、`connection`、`member` | 每次建连一次;重连再次执行 | 成员展示和连接策略 |
|
|
85
|
+
| `joinUnit` | 收到 `JOIN`,Session 加入当前 Worktree 房间前 | `worktreeID`、`session`、`unitID` | 当前 Session 首次 JOIN 时一次;Endpoint 不重试 | Worktree 与 Unit 读取 ACL |
|
|
86
|
+
| `receivePresence` | 已 JOIN 的 Session 发送 Presence、向房间广播前 | `worktreeID`、`session`、`unitID`、`payload`、事件级 `customData` | 每条 Presence 一次;Endpoint 不重试 | 校验、限流和过滤 |
|
|
87
|
+
| `sendPresence` | Presence 即将发送给当前 Worktree 的一个房间成员 | `worktreeID`、`session`、`unitID`、`payload`、事件级 `customData`、`targetMemberID` | 每个目标成员一次;发送失败不重试 | 按接收者过滤展示数据 |
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
worktreeEndpoint.use('joinUnit', async (ctx, next) => {
|
|
91
|
+
if (!await acl.canReadWorktreeUnit(
|
|
92
|
+
ctx.session.userID,
|
|
93
|
+
ctx.worktreeID,
|
|
94
|
+
ctx.unitID
|
|
95
|
+
)) {
|
|
96
|
+
throw new CollabError('PERMISSION_DENIED', 'Cannot join this Worktree Unit');
|
|
97
|
+
}
|
|
98
|
+
await next();
|
|
99
|
+
});
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`joinUnit` 只保护实时房间。Worktree 数据读取、提交和 merge 必须由 Worktree Service
|
|
103
|
+
middleware 保护;Service middleware 获取当前 HTTP 请求由 Transport 挂载的
|
|
104
|
+
`ctx.userID/customData`。
|
|
105
|
+
|
|
106
|
+
## 部署与资源释放
|
|
107
|
+
|
|
108
|
+
实时房间、状态事件和广播当前只保证单 Endpoint 进程。
|
|
109
|
+
|
|
110
|
+
Transport 释放已注册 Endpoint;Endpoint 不释放 Worktree Service、trunk Service 或
|
|
111
|
+
应用传入的 `ticketStore`。
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object['defineProperty'](exports,Symbol['toStringTag'],{'value':'Module'});let e=require('node:crypto'),t=require('@univerjs-pro/collaboration-endpoint'),n=require('@univerjs-pro/collaboration-service'),r=require('@univerjs-pro/collaboration-transport-node'),i=require('@univerjs-pro/collaboration-worktree-service'),a=require('@univerjs/protocol');var o=class{['_middlewares']=new Map();['use'](_0x57d056,_0x17bf70){let _0x5da80e=this['_middlewares']['get'](_0x57d056)??[],_0x2aebad=_0x17bf70;_0x5da80e['push'](_0x2aebad),this['_middlewares']['set'](_0x57d056,_0x5da80e);let _0x18a05d=!0x1;return{'dispose':()=>{if(_0x18a05d)return;_0x18a05d=!0x0;let _0x5c961a=_0x5da80e['indexOf'](_0x2aebad);_0x5c961a>=0x0&&_0x5da80e['splice'](_0x5c961a,0x1);}};}async['run'](_0x24ffe0,_0x4137bc,_0x559170){let _0x16c52f=[...this['_middlewares']['get'](_0x24ffe0)??[]],_0x864eb9=async _0x1e24b8=>{let _0x1c6cb5=_0x16c52f[_0x1e24b8];if(!_0x1c6cb5){await _0x559170();return;}let _0x349d20=!0x1,_0x32a7af;if(await _0x1c6cb5(_0x4137bc,()=>{if(_0x349d20)throw Error('Middleware\x20for\x20action\x20'+String(_0x24ffe0)+'\x20called\x20next()\x20twice');return _0x349d20=!0x0,_0x32a7af=_0x864eb9(_0x1e24b8+0x1),_0x32a7af;}),!_0x349d20)throw Error('Middleware\x20for\x20action\x20'+String(_0x24ffe0)+'\x20did\x20not\x20call\x20next()');await _0x32a7af;};await _0x864eb9(0x0);}['clear'](){this['_middlewares']['clear']();}},s=0x5*0xea60,c='/universer-api/worktrees',l='/universer-api/user/session-ticket',u=class{['_service'];['_options'];['_middleware']=new o();['_listeners']=new Map();['_scopedEndpoints']=new Map();['_connectionOwners']=new Map();['_connectionReady']=new Map();['_eventBindings']=new Map();['_eventRooms']=new Map();['_eventQueues']=new Map();['_subscriptions'];['_ticketTtlMs'];['_disposed']=!0x1;constructor(_0x516f02,_0x57efc2){if(this['_service']=_0x516f02,this['_options']=_0x57efc2,!_0x516f02)throw TypeError('UniverCollabWorktreeEndpoint\x20requires\x20a\x20Worktree\x20Service');if(!_0x57efc2?.['ticketStore'])throw TypeError('UniverCollabWorktreeEndpoint\x20requires\x20the\x20shared\x20ticketStore');if(this['_ticketTtlMs']=_0x57efc2['sessionTicketTtlMs']??s,!Number['isSafeInteger'](this['_ticketTtlMs'])||this['_ticketTtlMs']<=0x0)throw TypeError('sessionTicketTtlMs\x20must\x20be\x20a\x20positive\x20safe\x20integer');this['_subscriptions']=[this['_service']['on']('worktreeCreated',_0x344385=>this['_enqueueWorktreeChanged'](_0x344385['worktree'])),this['_service']['on']('worktreeUnitAdded',_0x5d0b8e=>this['_enqueueWorktreeChanged'](_0x5d0b8e['worktree'])),this['_service']['on']('worktreeUnitCreated',_0x43890f=>this['_enqueueWorktreeChanged'](_0x43890f['worktree'])),this['_service']['on']('worktreeStatusChanged',_0x534b7a=>this['_enqueueWorktreeChanged'](_0x534b7a['worktree'])),this['_service']['on']('worktreeUnitMergeResultRecorded',_0x1dbb57=>this['_enqueueWorktreeChanged'](_0x1dbb57['worktree']))];}['use'](_0x9d2084,_0xa1858d){return this['_assertRunning'](),this['_middleware']['use'](_0x9d2084,_0xa1858d);}['on'](_0x428ce2,_0x307051){this['_assertRunning']();let _0xfe6846=this['_listeners']['get'](_0x428ce2)??new Set(),_0x5ca323=_0x307051;_0xfe6846['add'](_0x5ca323),this['_listeners']['set'](_0x428ce2,_0xfe6846);let _0x10e453=!0x1;return{'dispose':()=>{_0x10e453||(_0x10e453=!0x0,_0xfe6846['delete'](_0x5ca323));}};}async['handle'](_0x516756,_0x356b03){if(this['_disposed']){await _0x356b03();return;}switch(_0x516756['kind']){case'http':await this['_handleHttp'](_0x516756,_0x356b03);return;case'websocket-open':await this['_handleOpen'](_0x516756,_0x356b03);return;case'websocket-message':{if(this['_eventBindings']['get'](_0x516756['connection']['id'])){_0x516756['connection']['close'](0x3eb,'Worktree\x20event\x20connection\x20is\x20server-only');return;}let _0x2f4436=this['_connectionOwners']['get'](_0x516756['connection']['id']);if(_0x2f4436){await this['_waitForConnectionReady'](_0x516756['connection']['id']),await _0x2f4436['handle'](_0x516756,_0x356b03);return;}await _0x356b03();return;}case'websocket-close':{if(this['_eventBindings']['has'](_0x516756['connection']['id'])){this['_removeEventBinding'](_0x516756['connection']['id']);return;}let _0x24c2ee=this['_connectionOwners']['get'](_0x516756['connection']['id']);if(_0x24c2ee){this['_connectionOwners']['delete'](_0x516756['connection']['id']),await this['_waitForConnectionReady'](_0x516756['connection']['id']),await _0x24c2ee['handle'](_0x516756,_0x356b03);return;}await _0x356b03();}}}async['dispose'](){if(this['_disposed'])return;this['_disposed']=!0x0,this['_subscriptions']['forEach'](_0x1c30e6=>_0x1c30e6['dispose']()),await Promise['allSettled']([...this['_eventQueues']['values']()]);for(let _0x2b4256 of this['_eventBindings']['values']())_0x2b4256['connection']['close'](0x3e9,'Endpoint\x20disposed');this['_eventBindings']['clear'](),this['_eventRooms']['clear'](),this['_eventQueues']['clear'](),this['_connectionOwners']['clear'](),this['_connectionReady']['clear']();let _0x41a39e=[...this['_scopedEndpoints']['values']()];this['_scopedEndpoints']['clear'](),await Promise['all'](_0x41a39e['map'](_0x175ab8=>_0x175ab8['dispose']())),this['_middleware']['clear'](),this['_listeners']['clear']();}async['_handleHttp'](_0x4252b3,_0x7d841e){let _0x121733;try{_0x121733=new URL(_0x4252b3['incomingMessage']['url']??'/','http://localhost');}catch(_0x55c501){this['_writeFailure'](_0x4252b3,_0x55c501);return;}if(_0x4252b3['incomingMessage']['method']==='GET'&&_0x121733['pathname']===l){try{this['_requireUser'](_0x4252b3);let _0x189e20=await this['_options']['ticketStore']['issue']({'userId':_0x4252b3['userId'],'customData':_0x4252b3['customData']},this['_ticketTtlMs']);T(_0x4252b3,0xc8,{'error':{'code':a['ErrorCode']['OK'],'message':''},'ticket':_0x189e20});}catch(_0x30a1f7){this['_writeFailure'](_0x4252b3,_0x30a1f7);}return;}let _0x146687,_0x54d988;try{_0x146687=p(_0x4252b3['incomingMessage']['method'],_0x121733['pathname']),_0x54d988=m(_0x121733['pathname']);}catch(_0x2239ed){this['_writeFailure'](_0x4252b3,_0x2239ed);return;}if(_0x146687){await this['_handleManagement'](_0x4252b3,_0x146687);return;}if(_0x54d988&&h(_0x54d988['suffix'])){await this['_scopedEndpoint'](_0x54d988['worktreeID'],_0x54d988['protocolBasePath'])['handle'](_0x4252b3,_0x7d841e);return;}await _0x7d841e();}async['_handleManagement'](_0x456a75,_0x59c6f2){try{this['_requireUser'](_0x456a75);let _0x4991db={'session':f(_0x456a75['userId']),'customData':_0x456a75['customData']};if(_0x59c6f2['action']==='evaluateUnitMerge'){let _0x55d253=await this['_service']['evaluateWorktreeUnitMerge']({'worktreeID':_0x59c6f2['worktreeID'],'unitID':_0x59c6f2['unitID']},_0x4991db);_0x456a75['response']['setHeader']('cache-control','no-store'),T(_0x456a75,0xc8,{'evaluation':_0x55d253});return;}let _0x351f5e;switch(_0x59c6f2['action']){case'create':{let _0x21a2da=await _0x456a75['readJson']();_(_0x21a2da),_0x351f5e=await this['_service']['createWorktree'](_0x21a2da,_0x4991db);break;}case'get':_0x351f5e=await this['_service']['getWorktree']({'worktreeID':_0x59c6f2['worktreeID']},_0x4991db);break;case'addUnit':{let _0x24fa7e=await _0x456a75['readJson']();v(_0x24fa7e),_0x351f5e=await this['_service']['addUnit']({'worktreeID':_0x59c6f2['worktreeID'],'unitID':_0x24fa7e['unitID']},_0x4991db);break;}case'createUnitFromSnapshot':{let _0x187fbf=y(await _0x456a75['readJson']());_0x351f5e=await this['_service']['createUnit']({'worktreeID':_0x59c6f2['worktreeID'],..._0x187fbf},_0x4991db);break;}case'createUnitFromData':{let _0xad8ad5=b(await _0x456a75['readJson']());_0x351f5e=await this['_service']['createUnitFromData']({'worktreeID':_0x59c6f2['worktreeID'],..._0xad8ad5},_0x4991db);break;}case'ready':_0x351f5e=await this['_service']['markReady']({'worktreeID':_0x59c6f2['worktreeID']},_0x4991db);break;case'reopen':_0x351f5e=await this['_service']['reopenWorktree']({'worktreeID':_0x59c6f2['worktreeID']},_0x4991db);break;case'discard':_0x351f5e=await this['_service']['discardWorktree']({'worktreeID':_0x59c6f2['worktreeID']},_0x4991db);break;case'merge':_0x351f5e=await this['_service']['mergeWorktree']({'worktreeID':_0x59c6f2['worktreeID']},_0x4991db);break;}T(_0x456a75,0xc8,{'worktree':_0x351f5e['worktree']});}catch(_0x9318d){this['_writeFailure'](_0x456a75,_0x9318d);}}async['_handleOpen'](_0xd7c8d2,_0x12f566){let _0x319daf,_0x319de0;try{_0x319daf=new URL(_0xd7c8d2['incomingMessage']['url']??'/','http://localhost'),_0x319de0=m(_0x319daf['pathname']);}catch{_0xd7c8d2['connection']['close'](0x3f0,'Invalid\x20Worktree\x20URL');return;}if(!_0x319de0){await _0x12f566();return;}if(_0x319de0['suffix']==='/events'){await this['_openEventConnection'](_0xd7c8d2,_0x319daf,_0x319de0['worktreeID']);return;}if(_0x319de0['suffix']==='/comb/connect'){let _0x4278b2=this['_scopedEndpoint'](_0x319de0['worktreeID'],_0x319de0['protocolBasePath']);this['_connectionOwners']['set'](_0xd7c8d2['connection']['id'],_0x4278b2);let _0x5463c4=Promise['resolve']()['then'](()=>_0x4278b2['handle'](_0xd7c8d2,_0x12f566));this['_connectionReady']['set'](_0xd7c8d2['connection']['id'],_0x5463c4);try{await _0x5463c4;}finally{this['_connectionReady']['get'](_0xd7c8d2['connection']['id'])===_0x5463c4&&this['_connectionReady']['delete'](_0xd7c8d2['connection']['id']);}return;}await _0x12f566();}async['_openEventConnection'](_0xcfd7db,_0x3c9b08,_0x578d10){try{let _0x4c2d1f=_0x3c9b08['searchParams']['get']('sessionTicket')??'',_0x6f730d=await this['_options']['ticketStore']['consume'](_0x4c2d1f);if(!_0x6f730d){_0xcfd7db['connection']['close'](0x3f0,'Invalid\x20or\x20expired\x20session\x20ticket');return;}let _0x2f8148=(0x0,e['randomUUID'])(),_0x2405e0={'memberId':_0x2f8148,'userId':_0x6f730d['userId'],'customData':_0x6f730d['customData']},_0x38cec9={'memberID':_0x2f8148,'userID':_0x6f730d['userId'],'name':_0x6f730d['userId']};await this['_middleware']['run']('connect',{'worktreeID':_0x578d10,'session':_0x2405e0,'connection':_0xcfd7db['connection'],'member':_0x38cec9},async()=>void 0x0);let _0x1584ab={'worktreeID':_0x578d10,'connection':_0xcfd7db['connection'],'session':_0x2405e0,'ready':!0x1};this['_eventBindings']['set'](_0xcfd7db['connection']['id'],_0x1584ab);let _0x3172e7=this['_eventRooms']['get'](_0x578d10)??new Map();_0x3172e7['set'](_0xcfd7db['connection']['id'],_0x1584ab),this['_eventRooms']['set'](_0x578d10,_0x3172e7);try{let {worktree:_0x507ea6}=await this['_service']['getWorktree']({'worktreeID':_0x578d10},{'session':_0x2405e0,'customData':_0xcfd7db['customData']});if(await this['_sendChanged'](_0x1584ab,_0x507ea6),_0x1584ab['ready']=!0x0,_0x1584ab['pending']){let _0x237f87=_0x1584ab['pending'];delete _0x1584ab['pending'],await this['_sendChanged'](_0x1584ab,_0x237f87);}}catch(_0x491f16){throw this['_removeEventBinding'](_0xcfd7db['connection']['id']),_0x491f16;}}catch(_0x3529f6){_0xcfd7db['connection']['close'](_0x3529f6 instanceof n['CollabError']||_0x3529f6 instanceof i['WorktreeError']?0x3f0:0x3f3,'Worktree\x20event\x20connection\x20rejected');}}['_scopedEndpoint'](_0x182c8c,_0x28cd27){let _0x1d8668=this['_scopedEndpoints']['get'](_0x182c8c);if(_0x1d8668)return _0x1d8668;let _0x23d6b3=new t['UniverCollabEndpoint'](new d(this['_service'],_0x182c8c),{'ticketStore':this['_options']['ticketStore'],'protocolBasePath':_0x28cd27});return _0x23d6b3['use']('connect',(_0x87dcf1,_0x1007cc)=>this['_middleware']['run']('connect',{..._0x87dcf1,'worktreeID':_0x182c8c},_0x1007cc)),_0x23d6b3['use']('joinUnit',async(_0x11b6f1,_0x3402e8)=>{let {worktree:_0x3e360b}=await this['_getJoinableWorktree'](_0x182c8c,_0x11b6f1['session']);if(!_0x3e360b['units']['some'](({unitID:_0x4c22ae})=>_0x4c22ae===_0x11b6f1['unitID']))throw new n['CollabError']('UNIT_NOT_FOUND','Unit\x20'+_0x11b6f1['unitID']+'\x20is\x20not\x20in\x20Worktree\x20'+_0x182c8c);await this['_middleware']['run']('joinUnit',{..._0x11b6f1,'worktreeID':_0x182c8c},_0x3402e8);}),_0x23d6b3['use']('receivePresence',(_0x4850ec,_0x54b478)=>this['_middleware']['run']('receivePresence',{..._0x4850ec,'worktreeID':_0x182c8c},_0x54b478)),_0x23d6b3['use']('sendPresence',(_0x25c08d,_0x4a83d7)=>this['_middleware']['run']('sendPresence',{..._0x25c08d,'worktreeID':_0x182c8c},_0x4a83d7)),_0x23d6b3['on']('memberLeftUnit',_0x552f67=>this['_emit']('memberLeftUnit',{..._0x552f67,'worktreeID':_0x182c8c})),this['_scopedEndpoints']['set'](_0x182c8c,_0x23d6b3),_0x23d6b3;}async['_getJoinableWorktree'](_0x4d3457,_0x1ff967){try{let _0x228b16=await this['_service']['getWorktree']({'worktreeID':_0x4d3457},{'session':_0x1ff967});if(_0x228b16['worktree']['status']==='discarded')throw new n['CollabError']('PERMISSION_DENIED','Discarded\x20Worktree\x20cannot\x20be\x20joined');return _0x228b16;}catch(_0xda4e7e){throw _0xda4e7e instanceof i['WorktreeError']&&_0xda4e7e['code']==='WORKTREE_NOT_FOUND'?new n['CollabError']('UNIT_NOT_FOUND',_0xda4e7e['message']):_0xda4e7e;}}['_enqueueWorktreeChanged'](_0x5bd196){if(this['_disposed'])return;let _0x604f2b=_0x5bd196['worktreeID'],_0x1be083=(this['_eventQueues']['get'](_0x604f2b)??Promise['resolve']())['catch'](()=>void 0x0)['then'](async()=>{let _0x4c7d56=[...this['_eventRooms']['get'](_0x604f2b)?.['values']()??[]];for(let _0xf6cca9 of _0x4c7d56){if(!_0xf6cca9['ready']){_0xf6cca9['pending']=_0x5bd196;continue;}await this['_sendChanged'](_0xf6cca9,_0x5bd196);}});this['_eventQueues']['set'](_0x604f2b,_0x1be083),_0x1be083['finally'](()=>{this['_eventQueues']['get'](_0x604f2b)===_0x1be083&&this['_eventQueues']['delete'](_0x604f2b);});}['_sendChanged'](_0x185453,_0x3129bc){let _0x533bfa={'event':'worktreeChanged','worktree':_0x3129bc};return Promise['resolve'](_0x185453['connection']['send'](JSON['stringify'](_0x533bfa)));}['_removeEventBinding'](_0x291f85){let _0x28441f=this['_eventBindings']['get'](_0x291f85);if(!_0x28441f)return;this['_eventBindings']['delete'](_0x291f85);let _0x4300ad=this['_eventRooms']['get'](_0x28441f['worktreeID']);_0x4300ad?.['delete'](_0x291f85),_0x4300ad?.['size']===0x0&&this['_eventRooms']['delete'](_0x28441f['worktreeID']);}async['_waitForConnectionReady'](_0x1a9c6b){try{await this['_connectionReady']['get'](_0x1a9c6b);}catch{}}async['_emit'](_0x50d594,_0x455c43){for(let _0x4d0c77 of[...this['_listeners']['get'](_0x50d594)??[]])try{await _0x4d0c77(_0x455c43);}catch{}}['_requireUser'](_0x2c9ca2){if(!_0x2c9ca2['userId'])throw new n['CollabError']('UNAUTHENTICATED','HTTP\x20user\x20is\x20not\x20authenticated');}['_writeFailure'](_0x428640,_0x2fe7e2){let _0x3ac9c6=E(_0x2fe7e2);T(_0x428640,_0x3ac9c6['status'],{'error':_0x3ac9c6['error']});}['_assertRunning'](){if(this['_disposed'])throw new n['CollabError']('INTERNAL_ERROR','Worktree\x20Endpoint\x20is\x20disposed');}},d=class{['_service'];['_worktreeID'];constructor(_0x474cb2,_0x40d141){this['_service']=_0x474cb2,this['_worktreeID']=_0x40d141;}['use'](){return{'dispose':()=>void 0x0};}['getUnit'](_0x4b5524,_0x12c785){return this['_service']['getUnit']({..._0x4b5524,'worktreeID':this['_worktreeID']},_0x12c785);}['getChangesets'](_0x458da5,_0x4b48c8){return this['_service']['getChangesets']({..._0x458da5,'worktreeID':this['_worktreeID']},_0x4b48c8);}['getSheetBlock'](_0x3d107a,_0x23be76){return this['_service']['getSheetBlock']({..._0x3d107a,'worktreeID':this['_worktreeID']},_0x23be76);}['createUnit'](_0x2e026a,_0x5441b1){return Promise['reject'](new n['CollabError']('INVALID_REQUEST','Cannot\x20create\x20a\x20Unit\x20through\x20a\x20Worktree\x20Endpoint'));}['createUnitFromData'](_0x25364e,_0x54aeed){return Promise['reject'](new n['CollabError']('INVALID_REQUEST','Cannot\x20create\x20a\x20Unit\x20through\x20a\x20Worktree\x20Endpoint'));}['deleteUnits'](_0x45001b,_0x10183b){return Promise['reject'](new n['CollabError']('INVALID_REQUEST','Cannot\x20delete\x20Units\x20through\x20a\x20Worktree\x20Endpoint'));}['recoverUnits'](_0x5ebb0,_0x19a07f){return Promise['reject'](new n['CollabError']('INVALID_REQUEST','Cannot\x20recover\x20Units\x20through\x20a\x20Worktree\x20Endpoint'));}['submitChangeset'](_0x5b3753,_0x62238d){return this['_service']['submitChangeset']({..._0x5b3753,'worktreeID':this['_worktreeID']},_0x62238d);}['on'](_0x1fbc30,_0xbcf1b0){return _0x1fbc30==='changesetCommitted'?this['_service']['on']('changesetCommitted',_0x175690=>{if(_0x175690['request']['worktreeID']===this['_worktreeID'])return _0xbcf1b0(_0x175690);}):{'dispose':()=>void 0x0};}['dispose'](){return Promise['resolve']();}};function f(_0x37808f){return{'memberId':'http-'+(0x0,e['randomUUID'])(),'userId':_0x37808f,'customData':Object['create'](null)};}function p(_0x47d387,_0x17893c){if(_0x47d387==='POST'&&_0x17893c===c)return{'action':'create'};let _0x4bec2b=_0x17893c['split']('/')['filter'](Boolean);if(_0x4bec2b['length']<0x3||_0x4bec2b[0x0]!=='universer-api'||_0x4bec2b[0x1]!=='worktrees')return null;let _0x2a145f=g(_0x4bec2b[0x2]);if(_0x47d387==='GET'&&_0x4bec2b['length']===0x3)return{'action':'get','worktreeID':_0x2a145f};if(_0x47d387==='GET'&&_0x4bec2b['length']===0x6&&_0x4bec2b[0x3]==='units'&&_0x4bec2b[0x5]==='merge-preview')return{'action':'evaluateUnitMerge','worktreeID':_0x2a145f,'unitID':g(_0x4bec2b[0x4])};if(_0x47d387==='POST'&&_0x4bec2b['length']===0x5&&_0x4bec2b[0x3]==='units'){let _0x576d0c={'from-snapshot':'createUnitFromSnapshot','from-data':'createUnitFromData'}[_0x4bec2b[0x4]];return _0x576d0c?{'action':_0x576d0c,'worktreeID':_0x2a145f}:null;}if(_0x47d387!=='POST'||_0x4bec2b['length']!==0x4)return null;let _0x2f5de4={'units':'addUnit','ready':'ready','reopen':'reopen','discard':'discard','merge':'merge'}[_0x4bec2b[0x3]];return _0x2f5de4?{'action':_0x2f5de4,'worktreeID':_0x2a145f}:null;}function m(_0x23d92a){let _0x408570=_0x23d92a['split']('/')['filter'](Boolean);if(_0x408570['length']<0x4||_0x408570[0x0]!=='universer-api'||_0x408570[0x1]!=='worktrees')return null;let _0x4e52d2=_0x408570[0x2],_0x4adf19=g(_0x4e52d2),_0x2fa850=c+'/'+encodeURIComponent(_0x4adf19);return _0x23d92a['startsWith'](_0x2fa850+'/')?{'worktreeID':_0x4adf19,'protocolBasePath':_0x2fa850,'suffix':_0x23d92a['slice'](_0x2fa850['length'])}:null;}function h(_0x384008){return _0x384008['startsWith']('/snapshot/')||_0x384008['startsWith']('/comb/');}function g(_0x2b8a8a){try{let _0x4b078e=decodeURIComponent(_0x2b8a8a);if(!_0x4b078e)throw Error('empty');return _0x4b078e;}catch{throw new n['CollabError']('INVALID_REQUEST','Route\x20contains\x20invalid\x20encoding');}}function _(_0xf4485e){if(!_0xf4485e||typeof _0xf4485e!='object'||typeof _0xf4485e['worktreeID']!='string')throw new n['CollabError']('INVALID_REQUEST','worktreeID\x20must\x20be\x20a\x20string');let _0x39b84e=_0xf4485e['units'];if(_0x39b84e!==void 0x0&&(!Array['isArray'](_0x39b84e)||_0x39b84e['some'](_0x470b8c=>typeof _0x470b8c!='string')))throw new n['CollabError']('INVALID_REQUEST','units\x20must\x20be\x20a\x20string\x20array');}function v(_0x2ace8b){if(!_0x2ace8b||typeof _0x2ace8b!='object'||typeof _0x2ace8b['unitID']!='string')throw new n['CollabError']('INVALID_REQUEST','unitID\x20must\x20be\x20a\x20string');}function y(_0x418a52){if(!C(_0x418a52)||!C(_0x418a52['snapshot']))throw new n['CollabError']('INVALID_REQUEST','snapshot\x20must\x20be\x20an\x20object');let _0x4733ab=_0x418a52['snapshot'];x(_0x4733ab);let _0x5b2bc0=_0x418a52['sheetBlocks'];if(_0x5b2bc0!==void 0x0&&(!Array['isArray'](_0x5b2bc0)||_0x5b2bc0['some'](_0x415232=>!C(_0x415232))))throw new n['CollabError']('INVALID_REQUEST','sheetBlocks\x20must\x20be\x20an\x20object\x20array');for(let _0x166965 of _0x5b2bc0??[])_0x166965['data']=S(_0x166965['data'],'sheetBlocks[].data');return{'snapshot':_0x4733ab,..._0x5b2bc0===void 0x0?{}:{'sheetBlocks':_0x5b2bc0}};}function b(_0x6546d7){if(!C(_0x6546d7)||!w['has'](_0x6546d7['type'])||!C(_0x6546d7['data']))throw new n['CollabError']('INVALID_REQUEST','type\x20and\x20data\x20must\x20describe\x20a\x20supported\x20Unit');return _0x6546d7;}function x(_0x2019b1){let _0x24fa4c=_0x2019b1['workbook']??_0x2019b1['doc']??_0x2019b1['slide']??_0x2019b1['board'];if(_0x24fa4c&&(_0x24fa4c['originalMeta']=S(_0x24fa4c['originalMeta'],'snapshot\x20originalMeta'),_0x2019b1['workbook'])){for(let _0x4437c6 of Object['values'](_0x2019b1['workbook']['sheets']))_0x4437c6['originalMeta']=S(_0x4437c6['originalMeta'],'snapshot\x20sheet\x20originalMeta');}}function S(_0x56457f,_0x11f0a5){if(_0x56457f instanceof Uint8Array)return _0x56457f;if(typeof _0x56457f!='string')throw new n['CollabError']('INVALID_REQUEST',_0x11f0a5+'\x20must\x20be\x20a\x20base64\x20string');try{return new Uint8Array(Buffer['from'](_0x56457f,'base64'));}catch{throw new n['CollabError']('INVALID_REQUEST',_0x11f0a5+'\x20must\x20be\x20valid\x20base64');}}function C(_0x5d8c5e){return!!_0x5d8c5e&&typeof _0x5d8c5e=='object'&&!Array['isArray'](_0x5d8c5e);}var w=new Set([a['UniverType']['UNIVER_SHEET'],a['UniverType']['UNIVER_DOC'],a['UniverType']['UNIVER_SLIDE'],a['UniverType']['UNIVER_BOARD'],a['UniverType']['UNIVER_BASE']]);function T(_0x2ff044,_0x5b15a4,_0x3b319b){let _0xcde8bd=_0x2ff044['response'];_0xcde8bd['writableEnded']||_0xcde8bd['destroyed']||(_0xcde8bd['statusCode']=_0x5b15a4,_0xcde8bd['setHeader']('content-type','application/json;\x20charset=utf-8'),_0xcde8bd['end'](JSON['stringify'](_0x3b319b,(_0x21612f,_0x1bbda9)=>_0x1bbda9 instanceof Uint8Array?Buffer['from'](_0x1bbda9)['toString']('base64'):_0x1bbda9)));}function E(_0x342008){return _0x342008 instanceof r['NodeTransportError']?{'status':_0x342008['code']==='REQUEST_BODY_TOO_LARGE'?0x19d:_0x342008['code']==='INVALID_JSON'||_0x342008['code']==='REQUEST_ABORTED'?0x190:0x1f7,'error':{'code':_0x342008['code'],'message':_0x342008['message']}}:_0x342008 instanceof i['WorktreeError']?{'status':_0x342008['code']==='WORKTREE_NOT_FOUND'||_0x342008['code']==='WORKTREE_UNIT_NOT_FOUND'?0x194:0x199,'error':{'code':_0x342008['code'],'message':_0x342008['message'],'retryable':_0x342008['retryable']}}:_0x342008 instanceof n['CollabError']?{'status':{'UNAUTHENTICATED':0x191,'INVALID_REQUEST':0x190,'UNIT_NOT_FOUND':0x194,'PERMISSION_DENIED':0x193,'OT_CONFLICT':0x199,'REVISION_MISMATCH':0x199,'ADAPTER_FAILURE':0x1f7,'INTERNAL_ERROR':0x1f4}[_0x342008['code']],'error':{'code':_0x342008['code'],'message':_0x342008['message'],'retryable':_0x342008['retryable']}}:{'status':0x1f4,'error':{'code':'INTERNAL_ERROR','message':'Internal\x20server\x20error'}};}exports['UniverCollabWorktreeEndpoint']=u;
|
|
1
|
+
Object['defineProperty'](exports,Symbol['toStringTag'],{'value':'Module'});let e=require('node:crypto'),t=require('@univerjs-pro/collaboration-endpoint'),n=require('@univerjs-pro/collaboration-service'),r=require('@univerjs-pro/collaboration-transport-node'),i=require('@univerjs-pro/collaboration-worktree-service'),a=require('@univerjs/protocol');var o=class{['_middlewares']=new Map();['use'](_0x404b9c,_0x4161e4){let _0x13d4b9=this['_middlewares']['get'](_0x404b9c)??[],_0x1232b4=_0x4161e4;_0x13d4b9['push'](_0x1232b4),this['_middlewares']['set'](_0x404b9c,_0x13d4b9);let _0xb94060=!0x1;return{'dispose':()=>{if(_0xb94060)return;_0xb94060=!0x0;let _0x4ab94a=_0x13d4b9['indexOf'](_0x1232b4);_0x4ab94a>=0x0&&_0x13d4b9['splice'](_0x4ab94a,0x1);}};}async['run'](_0x1c1ef3,_0x57ebd4,_0x14b53d){let _0x3fe3d7=[...this['_middlewares']['get'](_0x1c1ef3)??[]],_0x462e94=async _0x2d9eeb=>{let _0x4bb132=_0x3fe3d7[_0x2d9eeb];if(!_0x4bb132){await _0x14b53d();return;}let _0x38baa2=!0x1,_0x2eb933;if(await _0x4bb132(_0x57ebd4,()=>{if(_0x38baa2)throw Error('Middleware\x20for\x20action\x20'+String(_0x1c1ef3)+'\x20called\x20next()\x20twice');return _0x38baa2=!0x0,_0x2eb933=_0x462e94(_0x2d9eeb+0x1),_0x2eb933;}),!_0x38baa2)throw Error('Middleware\x20for\x20action\x20'+String(_0x1c1ef3)+'\x20did\x20not\x20call\x20next()');await _0x2eb933;};await _0x462e94(0x0);}['clear'](){this['_middlewares']['clear']();}},s=0x5*0xea60,c='/universer-api/worktrees',l='/universer-api/user/session-ticket',u=class{['_service'];['_options'];['_middleware']=new o();['_listeners']=new Map();['_scopedEndpoints']=new Map();['_eventBindings']=new Map();['_eventRooms']=new Map();['_eventQueues']=new Map();['_subscriptions'];['_ticketTtlMs'];['_disposed']=!0x1;constructor(_0x506dd9,_0x19887f){if(this['_service']=_0x506dd9,this['_options']=_0x19887f,!_0x506dd9)throw TypeError('UniverCollabWorktreeEndpoint\x20requires\x20a\x20Worktree\x20Service');if(!_0x19887f?.['ticketStore'])throw TypeError('UniverCollabWorktreeEndpoint\x20requires\x20the\x20shared\x20ticketStore');if(this['_ticketTtlMs']=_0x19887f['sessionTicketTtlMs']??s,!Number['isSafeInteger'](this['_ticketTtlMs'])||this['_ticketTtlMs']<=0x0)throw TypeError('sessionTicketTtlMs\x20must\x20be\x20a\x20positive\x20safe\x20integer');this['_subscriptions']=[this['_service']['on']('worktreeUnitRemovalChanged',_0x5236b6=>this['_enqueueWorktreeChanged'](_0x5236b6['worktree'])),this['_service']['on']('worktreeCreated',_0x5e5c7a=>this['_enqueueWorktreeChanged'](_0x5e5c7a['worktree'])),this['_service']['on']('worktreeUnitAdded',_0x26955d=>this['_enqueueWorktreeChanged'](_0x26955d['worktree'])),this['_service']['on']('worktreeUnitCreated',_0x228211=>this['_enqueueWorktreeChanged'](_0x228211['worktree'])),this['_service']['on']('worktreeStatusChanged',_0x4b65cb=>this['_enqueueWorktreeChanged'](_0x4b65cb['worktree'])),this['_service']['on']('worktreeUnitMergeResultRecorded',_0x2d929b=>this['_enqueueWorktreeChanged'](_0x2d929b['worktree']))];}['use'](_0x4a1431,_0x44961e){return this['_assertRunning'](),this['_middleware']['use'](_0x4a1431,_0x44961e);}['on'](_0x49a8e3,_0xfb3d86){this['_assertRunning']();let _0x567dce=this['_listeners']['get'](_0x49a8e3)??new Set(),_0x1d5ec9=_0xfb3d86;_0x567dce['add'](_0x1d5ec9),this['_listeners']['set'](_0x49a8e3,_0x567dce);let _0x3c70fe=!0x1;return{'dispose':()=>{_0x3c70fe||(_0x3c70fe=!0x0,_0x567dce['delete'](_0x1d5ec9));}};}['register'](_0x4940fa){this['_assertRunning'](),_0x4940fa['get'](l,_0x3a44d4=>this['_handleTicket'](_0x3a44d4));let _0x13de8d=_0x13dcc3=>_0x47e6a8=>this['_handleManagement'](_0x47e6a8,{..._0x47e6a8['params'],'action':_0x13dcc3});_0x4940fa['post'](c,_0x13de8d('create')),_0x4940fa['get'](c+'/:worktreeID',_0x13de8d('get')),_0x4940fa['get'](c+'/:worktreeID/units/:unitID/merge-preview',_0x13de8d('evaluateUnitMerge'));for(let [_0x26351c,_0x1588ba]of[['units','addUnit'],['units/:unitID/removal','setUnitRemoved'],['units/from-snapshot','createUnitFromSnapshot'],['units/from-data','createUnitFromData'],['ready','ready'],['reopen','reopen'],['discard','discard'],['merge','merge']])_0x4940fa['post'](c+'/:worktreeID/'+_0x26351c,_0x13de8d(_0x1588ba));for(let [_0xd39b99,_0x62e204]of[['get','/snapshot/:type/unit/:unitID/rev/:revision'],['get','/snapshot/:type/unit/:unitID/block/:blockID'],['get','/snapshot/block/:type/unit/:unitID/block/:blockID'],['get','/snapshot/:type/unit/:unitID/fetchmissing'],['post','/comb/:type/unit/:unitID/new_changes'],['delete','/snapshot/-/units'],['post','/snapshot/-/units/recover']]){let _0x1793d4=c+'/:worktreeID'+_0x62e204;_0x4940fa[_0xd39b99](_0x1793d4,_0x3c0097=>{let _0x34880b=this['_scopedEndpoint'](_0x3c0097['params']['worktreeID'])['http']['get'](_0xd39b99+'\x20'+_0x1793d4);if(!_0x34880b)throw Error('Scoped\x20collaboration\x20HTTP\x20route\x20is\x20not\x20registered');return _0x34880b(_0x3c0097);});}let _0xb76c79=c+'/:worktreeID/comb/connect';_0x4940fa['upgrade'](_0xb76c79,_0x3dc218=>{let _0x38d3b8=this['_scopedEndpoint'](_0x3dc218['params']['worktreeID'])['upgrade']['get'](_0xb76c79);if(!_0x38d3b8)throw Error('Scoped\x20collaboration\x20upgrade\x20route\x20is\x20not\x20registered');return _0x38d3b8(_0x3dc218);}),_0x4940fa['upgrade'](c+'/:worktreeID/events',_0x580c9d=>this['_handleEventUpgrade'](_0x580c9d));}async['_handleEventUpgrade'](_0x285d41){this['_assertRunning']();let _0x594682=new URL(_0x285d41['incomingMessage']['url']??'/','http://localhost'),_0x3cba51=await this['_options']['ticketStore']['consume'](_0x594682['searchParams']['get']('sessionTicket')??'');if(!_0x3cba51){_0x285d41['reject'](0x191,'Invalid\x20or\x20expired\x20session\x20ticket');return;}let _0x4113b7=_0x285d41['params']['worktreeID'];_0x285d41['accept']({'open':({connection:_0x3e11d7})=>this['_openEventConnection'](_0x3e11d7,_0x3cba51,_0x4113b7),'message':({connection:_0x4902a4})=>_0x4902a4['close'](0x3eb,'Worktree\x20event\x20connection\x20is\x20server-only'),'close':({connection:_0x2b8532})=>this['_removeEventBinding'](_0x2b8532['id'])});}async['dispose'](){if(this['_disposed'])return;this['_disposed']=!0x0,this['_subscriptions']['forEach'](_0x38e046=>_0x38e046['dispose']()),await Promise['allSettled']([...this['_eventQueues']['values']()]);for(let _0x596113 of this['_eventBindings']['values']())_0x596113['connection']['close'](0x3e9,'Endpoint\x20disposed');this['_eventBindings']['clear'](),this['_eventRooms']['clear'](),this['_eventQueues']['clear']();let _0x49238c=[...this['_scopedEndpoints']['values']()];this['_scopedEndpoints']['clear'](),await Promise['all'](_0x49238c['map'](({endpoint:_0x22d3d3})=>_0x22d3d3['dispose']())),this['_middleware']['clear'](),this['_listeners']['clear']();}async['_handleTicket'](_0x1c5463){try{this['_assertRunning'](),this['_requireUser'](_0x1c5463);let _0x19a2a7=await this['_options']['ticketStore']['issue']({'userID':_0x1c5463['userID'],'customData':_0x1c5463['customData']},this['_ticketTtlMs']);b(_0x1c5463,0xc8,{'error':{'code':a['ErrorCode']['OK'],'message':''},'ticket':_0x19a2a7});}catch(_0xa3955c){this['_writeFailure'](_0x1c5463,_0xa3955c);}}async['_handleManagement'](_0x153248,_0x4e0088){try{this['_assertRunning'](),this['_requireUser'](_0x153248);let _0x470a55={'userID':_0x153248['userID'],'customData':_0x153248['customData']};if(_0x4e0088['action']==='evaluateUnitMerge'){let _0x573cb4=await this['_service']['evaluateWorktreeUnitMerge']({'worktreeID':_0x4e0088['worktreeID'],'unitID':_0x4e0088['unitID']},_0x470a55);_0x153248['response']['setHeader']('cache-control','no-store'),b(_0x153248,0xc8,{'evaluation':_0x573cb4});return;}let _0x4a00e5;switch(_0x4e0088['action']){case'create':{let _0x2826eb=await _0x153248['readJson']();f(_0x2826eb),_0x4a00e5=await this['_service']['createWorktree'](_0x2826eb,_0x470a55);break;}case'get':_0x4a00e5=await this['_service']['getWorktree']({'worktreeID':_0x4e0088['worktreeID']},_0x470a55);break;case'setUnitRemoved':{let _0x2165f5=await _0x153248['readJson']();if(!v(_0x2165f5)||typeof _0x2165f5['removed']!='boolean')throw new n['CollabError']('INVALID_REQUEST','removed\x20must\x20be\x20a\x20boolean');_0x4a00e5=await this['_service']['setUnitRemoved']({'worktreeID':_0x4e0088['worktreeID'],'unitID':_0x4e0088['unitID'],'removed':_0x2165f5['removed']},_0x470a55);break;}case'addUnit':{let _0x30cd11=await _0x153248['readJson']();p(_0x30cd11),_0x4a00e5=await this['_service']['addUnit']({'worktreeID':_0x4e0088['worktreeID'],'unitID':_0x30cd11['unitID']},_0x470a55);break;}case'createUnitFromSnapshot':{let _0x5a07c1=m(await _0x153248['readJson']());_0x4a00e5=await this['_service']['createUnitFromSnapshot']({'worktreeID':_0x4e0088['worktreeID'],..._0x5a07c1},_0x470a55);break;}case'createUnitFromData':{let _0x364800=h(await _0x153248['readJson']());_0x4a00e5=await this['_service']['createUnitFromData']({'worktreeID':_0x4e0088['worktreeID'],..._0x364800},_0x470a55);break;}case'ready':_0x4a00e5=await this['_service']['markReady']({'worktreeID':_0x4e0088['worktreeID']},_0x470a55);break;case'reopen':_0x4a00e5=await this['_service']['reopenWorktree']({'worktreeID':_0x4e0088['worktreeID']},_0x470a55);break;case'discard':_0x4a00e5=await this['_service']['discardWorktree']({'worktreeID':_0x4e0088['worktreeID']},_0x470a55);break;case'merge':_0x4a00e5=await this['_service']['mergeWorktree']({'worktreeID':_0x4e0088['worktreeID']},{..._0x470a55,'memberID':'http-'+(0x0,e['randomUUID'])()});break;}b(_0x153248,0xc8,{'worktree':_0x4a00e5['worktree']});}catch(_0x28143f){this['_writeFailure'](_0x153248,_0x28143f);}}async['_openEventConnection'](_0x1469f3,_0x3d7da5,_0x38de32){try{let _0x3027fb=(0x0,e['randomUUID'])(),_0x5ed3d6={'memberID':_0x3027fb,'userID':_0x3d7da5['userID'],'customData':_0x3d7da5['customData']},_0x1cb11f={'memberID':_0x3027fb,'userID':_0x3d7da5['userID'],'name':_0x3d7da5['userID']};await this['_middleware']['run']('connect',{'worktreeID':_0x38de32,'session':_0x5ed3d6,'connection':_0x1469f3,'member':_0x1cb11f},async()=>void 0x0);let _0x17b6e1={'worktreeID':_0x38de32,'connection':_0x1469f3,'session':_0x5ed3d6,'ready':!0x1};this['_eventBindings']['set'](_0x1469f3['id'],_0x17b6e1);let _0x165faa=this['_eventRooms']['get'](_0x38de32)??new Map();_0x165faa['set'](_0x1469f3['id'],_0x17b6e1),this['_eventRooms']['set'](_0x38de32,_0x165faa);try{let {worktree:_0x4ce549}=await this['_service']['getWorktree']({'worktreeID':_0x38de32},{'userID':_0x5ed3d6['userID'],'customData':_0x1469f3['customData']});if(await this['_sendChanged'](_0x17b6e1,_0x4ce549),_0x17b6e1['ready']=!0x0,_0x17b6e1['pending']){let _0x30a1f1=_0x17b6e1['pending'];delete _0x17b6e1['pending'],await this['_sendChanged'](_0x17b6e1,_0x30a1f1);}}catch(_0x495839){throw this['_removeEventBinding'](_0x1469f3['id']),_0x495839;}}catch(_0x55749a){_0x1469f3['close'](_0x55749a instanceof n['CollabError']||_0x55749a instanceof i['WorktreeError']?0x3f0:0x3f3,'Worktree\x20event\x20connection\x20rejected');}}['_scopedEndpoint'](_0x1710f2){this['_assertRunning']();let _0x4a0cfd=this['_scopedEndpoints']['get'](_0x1710f2);if(_0x4a0cfd)return _0x4a0cfd;let _0x17d15b=new t['UniverCollabEndpoint'](new d(this['_service'],_0x1710f2),{'ticketStore':this['_options']['ticketStore'],'protocolBasePath':c+'/:worktreeID'});_0x17d15b['use']('connect',(_0x3b619b,_0x1b8b11)=>this['_middleware']['run']('connect',{..._0x3b619b,'worktreeID':_0x1710f2},_0x1b8b11)),_0x17d15b['use']('joinUnit',async(_0x52ae49,_0xe5ed1e)=>{let {worktree:_0x3c5f50}=await this['_getJoinableWorktree'](_0x1710f2,_0x52ae49['session']);if(!_0x3c5f50['units']['some'](({unitID:_0x575d29})=>_0x575d29===_0x52ae49['unitID']))throw new n['CollabError']('UNIT_NOT_FOUND','Unit\x20'+_0x52ae49['unitID']+'\x20is\x20not\x20in\x20Worktree\x20'+_0x1710f2);await this['_middleware']['run']('joinUnit',{..._0x52ae49,'worktreeID':_0x1710f2},_0xe5ed1e);}),_0x17d15b['use']('receivePresence',(_0xe04f7f,_0x2b4890)=>this['_middleware']['run']('receivePresence',{..._0xe04f7f,'worktreeID':_0x1710f2},_0x2b4890)),_0x17d15b['use']('sendPresence',(_0x23d7be,_0x263054)=>this['_middleware']['run']('sendPresence',{..._0x23d7be,'worktreeID':_0x1710f2},_0x263054)),_0x17d15b['on']('memberLeftUnit',_0x534ac6=>this['_emit']('memberLeftUnit',{..._0x534ac6,'worktreeID':_0x1710f2}));let _0xab8ff7=new Map(),_0x1b00ed=new Map();_0x17d15b['register']({'get':(_0x6fb5aa,_0x71c940)=>{_0xab8ff7['set']('get\x20'+_0x6fb5aa,_0x71c940);},'post':(_0x26ec6f,_0x23d716)=>{_0xab8ff7['set']('post\x20'+_0x26ec6f,_0x23d716);},'delete':(_0xf6fa5f,_0x126b1c)=>{_0xab8ff7['set']('delete\x20'+_0xf6fa5f,_0x126b1c);},'upgrade':(_0x2be682,_0x42926a)=>{_0x1b00ed['set'](_0x2be682,_0x42926a);}});let _0x1da0c3={'endpoint':_0x17d15b,'http':_0xab8ff7,'upgrade':_0x1b00ed};return this['_scopedEndpoints']['set'](_0x1710f2,_0x1da0c3),_0x1da0c3;}async['_getJoinableWorktree'](_0x5c962f,_0x2ea6cf){try{let _0x2e463e=await this['_service']['getWorktree']({'worktreeID':_0x5c962f},{'userID':_0x2ea6cf['userID']});if(_0x2e463e['worktree']['status']==='discarded')throw new n['CollabError']('PERMISSION_DENIED','Discarded\x20Worktree\x20cannot\x20be\x20joined');return _0x2e463e;}catch(_0x468511){throw _0x468511 instanceof i['WorktreeError']&&_0x468511['code']==='WORKTREE_NOT_FOUND'?new n['CollabError']('UNIT_NOT_FOUND',_0x468511['message']):_0x468511;}}['_enqueueWorktreeChanged'](_0x43940f){if(this['_disposed'])return;let _0x28e842=_0x43940f['worktreeID'],_0x4327d4=(this['_eventQueues']['get'](_0x28e842)??Promise['resolve']())['catch'](()=>void 0x0)['then'](async()=>{let _0x4cb2f6=[...this['_eventRooms']['get'](_0x28e842)?.['values']()??[]];for(let _0x10104c of _0x4cb2f6){if(!_0x10104c['ready']){_0x10104c['pending']=_0x43940f;continue;}await this['_sendChanged'](_0x10104c,_0x43940f);}});this['_eventQueues']['set'](_0x28e842,_0x4327d4),_0x4327d4['finally'](()=>{this['_eventQueues']['get'](_0x28e842)===_0x4327d4&&this['_eventQueues']['delete'](_0x28e842);});}['_sendChanged'](_0xa603cb,_0x35a2d8){let _0x1fe4d1={'event':'worktreeChanged','worktree':_0x35a2d8};return Promise['resolve'](_0xa603cb['connection']['send'](JSON['stringify'](_0x1fe4d1)));}['_removeEventBinding'](_0x494517){let _0x35da8b=this['_eventBindings']['get'](_0x494517);if(!_0x35da8b)return;this['_eventBindings']['delete'](_0x494517);let _0x4cbb26=this['_eventRooms']['get'](_0x35da8b['worktreeID']);_0x4cbb26?.['delete'](_0x494517),_0x4cbb26?.['size']===0x0&&this['_eventRooms']['delete'](_0x35da8b['worktreeID']);}async['_emit'](_0xdd0fb6,_0x2ef057){for(let _0x2ed960 of[...this['_listeners']['get'](_0xdd0fb6)??[]])try{await _0x2ed960(_0x2ef057);}catch{}}['_requireUser'](_0x53f927){if(!_0x53f927['userID'])throw new n['CollabError']('UNAUTHENTICATED','HTTP\x20user\x20is\x20not\x20authenticated');}['_writeFailure'](_0x4d3b24,_0x15fa2e){let _0x266256=x(_0x15fa2e);b(_0x4d3b24,_0x266256['status'],{'error':_0x266256['error']});}['_assertRunning'](){if(this['_disposed'])throw new n['CollabError']('INTERNAL_ERROR','Worktree\x20Endpoint\x20is\x20disposed');}},d=class{['_service'];['_worktreeID'];constructor(_0x34fa4e,_0x30cfdd){this['_service']=_0x34fa4e,this['_worktreeID']=_0x30cfdd;}['use'](){return{'dispose':()=>void 0x0};}['getUnitLoadData'](_0x30a48d,_0x2a0515){return this['_service']['getUnitLoadData']({..._0x30a48d,'worktreeID':this['_worktreeID']},_0x2a0515);}['getUnitLoadDataWithBlocks'](_0x524bea,_0x48f2e6){return Promise['reject'](new n['CollabError']('INVALID_REQUEST','Cannot\x20read\x20Unit\x20blocks\x20through\x20a\x20Worktree\x20Endpoint'));}['getChangesets'](_0x582d33,_0x268bb9){return this['_service']['getChangesets']({..._0x582d33,'worktreeID':this['_worktreeID']},_0x268bb9);}['getSheetBlock'](_0x1d2606,_0x40e702){return this['_service']['getSheetBlock']({..._0x1d2606,'worktreeID':this['_worktreeID']},_0x40e702);}['createUnitFromSnapshot'](_0x569d9d,_0xc59b40){return Promise['reject'](new n['CollabError']('INVALID_REQUEST','Cannot\x20create\x20a\x20Unit\x20through\x20a\x20Worktree\x20Endpoint'));}['createUnitFromData'](_0x137843,_0x26c9f3){return Promise['reject'](new n['CollabError']('INVALID_REQUEST','Cannot\x20create\x20a\x20Unit\x20through\x20a\x20Worktree\x20Endpoint'));}['deleteUnits'](_0x11f459,_0x4b45a2){return Promise['reject'](new n['CollabError']('INVALID_REQUEST','Cannot\x20delete\x20Units\x20through\x20a\x20Worktree\x20Endpoint'));}['recoverUnits'](_0x1ce64b,_0xd7ef6e){return Promise['reject'](new n['CollabError']('INVALID_REQUEST','Cannot\x20recover\x20Units\x20through\x20a\x20Worktree\x20Endpoint'));}['submitChangeset'](_0x3c1c52,_0x13ea00){return this['_service']['submitChangeset']({..._0x3c1c52,'worktreeID':this['_worktreeID']},_0x13ea00);}['on'](_0x3bbea3,_0x15cad){return _0x3bbea3==='changesetCommitted'?this['_service']['on']('changesetCommitted',_0x2ba2b8=>{if(_0x2ba2b8['request']['worktreeID']===this['_worktreeID'])return _0x15cad(_0x2ba2b8);}):{'dispose':()=>void 0x0};}['dispose'](){return Promise['resolve']();}};function f(_0x4e4497){if(!_0x4e4497||typeof _0x4e4497!='object'||typeof _0x4e4497['worktreeID']!='string')throw new n['CollabError']('INVALID_REQUEST','worktreeID\x20must\x20be\x20a\x20string');let _0x32b15a=_0x4e4497['units'];if(_0x32b15a!==void 0x0&&(!Array['isArray'](_0x32b15a)||_0x32b15a['some'](_0x2e72c7=>typeof _0x2e72c7!='string')))throw new n['CollabError']('INVALID_REQUEST','units\x20must\x20be\x20a\x20string\x20array');}function p(_0x5c0752){if(!_0x5c0752||typeof _0x5c0752!='object'||typeof _0x5c0752['unitID']!='string')throw new n['CollabError']('INVALID_REQUEST','unitID\x20must\x20be\x20a\x20string');}function m(_0x6ff1e5){if(!v(_0x6ff1e5)||!v(_0x6ff1e5['snapshot']))throw new n['CollabError']('INVALID_REQUEST','snapshot\x20must\x20be\x20an\x20object');let _0x3861a0=_0x6ff1e5['snapshot'];g(_0x3861a0);let _0x2f7b86=_0x6ff1e5['sheetBlocks'];if(_0x2f7b86!==void 0x0&&(!Array['isArray'](_0x2f7b86)||_0x2f7b86['some'](_0x16899d=>!v(_0x16899d))))throw new n['CollabError']('INVALID_REQUEST','sheetBlocks\x20must\x20be\x20an\x20object\x20array');for(let _0x5b9ac7 of _0x2f7b86??[])_0x5b9ac7['data']=_(_0x5b9ac7['data'],'sheetBlocks[].data');return{'snapshot':_0x3861a0,'sheetBlocks':_0x2f7b86??[]};}function h(_0x4598cd){if(!v(_0x4598cd)||!y['has'](_0x4598cd['type'])||!v(_0x4598cd['data']))throw new n['CollabError']('INVALID_REQUEST','type\x20and\x20data\x20must\x20describe\x20a\x20supported\x20Unit');return _0x4598cd;}function g(_0x3780b4){let _0x2445e4=_0x3780b4['workbook']??_0x3780b4['doc']??_0x3780b4['slide']??_0x3780b4['board'];if(_0x2445e4&&(_0x2445e4['originalMeta']=_(_0x2445e4['originalMeta'],'snapshot\x20originalMeta'),_0x3780b4['workbook'])){for(let _0x21206e of Object['values'](_0x3780b4['workbook']['sheets']))_0x21206e['originalMeta']=_(_0x21206e['originalMeta'],'snapshot\x20sheet\x20originalMeta');}}function _(_0x1a9f00,_0x28554e){if(_0x1a9f00 instanceof Uint8Array)return _0x1a9f00;if(typeof _0x1a9f00!='string')throw new n['CollabError']('INVALID_REQUEST',_0x28554e+'\x20must\x20be\x20a\x20base64\x20string');try{return new Uint8Array(Buffer['from'](_0x1a9f00,'base64'));}catch{throw new n['CollabError']('INVALID_REQUEST',_0x28554e+'\x20must\x20be\x20valid\x20base64');}}function v(_0x254898){return!!_0x254898&&typeof _0x254898=='object'&&!Array['isArray'](_0x254898);}var y=new Set([a['UniverType']['UNIVER_SHEET'],a['UniverType']['UNIVER_DOC'],a['UniverType']['UNIVER_SLIDE'],a['UniverType']['UNIVER_BOARD'],a['UniverType']['UNIVER_BASE']]);function b(_0x546500,_0x50eae2,_0x4d2da1){let _0xcf3dc1=_0x546500['response'];_0xcf3dc1['writableEnded']||_0xcf3dc1['destroyed']||(_0xcf3dc1['statusCode']=_0x50eae2,_0xcf3dc1['setHeader']('content-type','application/json;\x20charset=utf-8'),_0xcf3dc1['end'](JSON['stringify'](_0x4d2da1,(_0x46d942,_0x5392c9)=>_0x5392c9 instanceof Uint8Array?Buffer['from'](_0x5392c9)['toString']('base64'):_0x5392c9)));}function x(_0x22925f){return _0x22925f instanceof r['NodeTransportError']?{'status':_0x22925f['code']==='REQUEST_BODY_TOO_LARGE'?0x19d:_0x22925f['code']==='INVALID_JSON'||_0x22925f['code']==='REQUEST_ABORTED'?0x190:0x1f7,'error':{'code':_0x22925f['code'],'message':_0x22925f['message']}}:_0x22925f instanceof i['WorktreeError']?{'status':_0x22925f['code']==='WORKTREE_NOT_FOUND'||_0x22925f['code']==='WORKTREE_UNIT_NOT_FOUND'?0x194:0x199,'error':{'code':_0x22925f['code'],'message':_0x22925f['message'],'retryable':_0x22925f['retryable']}}:_0x22925f instanceof n['CollabError']?{'status':{'UNAUTHENTICATED':0x191,'INVALID_REQUEST':0x190,'UNIT_NOT_FOUND':0x194,'PERMISSION_DENIED':0x193,'OT_CONFLICT':0x199,'REVISION_MISMATCH':0x199,'ADAPTER_FAILURE':0x1f7,'INTERNAL_ERROR':0x1f4}[_0x22925f['code']],'error':{'code':_0x22925f['code'],'message':_0x22925f['message'],'retryable':_0x22925f['retryable']}}:{'status':0x1f4,'error':{'code':'INTERNAL_ERROR','message':'Internal\x20server\x20error'}};}exports['UniverCollabWorktreeEndpoint']=u;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { EndpointMember, ISessionTicketStore } from "@univerjs-pro/collaboration-endpoint";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { EndpointMember, EndpointSession, ISessionTicketStore, MemberLeftUnitReason } from "@univerjs-pro/collaboration-endpoint";
|
|
2
|
+
import { Disposable } from "@univerjs-pro/collaboration-service";
|
|
3
|
+
import { NodeRouter, NodeTransportConnection, NodeTransportEndpoint } from "@univerjs-pro/collaboration-transport-node";
|
|
4
4
|
import { IUniverCollabWorktreeService, WorktreeData } from "@univerjs-pro/collaboration-worktree-service";
|
|
5
5
|
|
|
6
6
|
//#region src/worktree-endpoint.d.ts
|
|
@@ -10,7 +10,7 @@ interface UniverCollabWorktreeEndpointOptions {
|
|
|
10
10
|
}
|
|
11
11
|
interface BaseWorktreeEndpointMiddlewareContext {
|
|
12
12
|
readonly worktreeID: string;
|
|
13
|
-
readonly session:
|
|
13
|
+
readonly session: EndpointSession;
|
|
14
14
|
}
|
|
15
15
|
interface ConnectWorktreeEndpointMiddlewareContext extends BaseWorktreeEndpointMiddlewareContext {
|
|
16
16
|
readonly connection: NodeTransportConnection;
|
|
@@ -24,7 +24,7 @@ interface ReceiveWorktreePresenceEndpointMiddlewareContext extends JoinWorktreeU
|
|
|
24
24
|
readonly customData: Record<string, unknown>;
|
|
25
25
|
}
|
|
26
26
|
interface SendWorktreePresenceEndpointMiddlewareContext extends ReceiveWorktreePresenceEndpointMiddlewareContext {
|
|
27
|
-
readonly
|
|
27
|
+
readonly targetMemberID: string;
|
|
28
28
|
}
|
|
29
29
|
type WorktreeEndpointMiddlewareAction = "connect" | "joinUnit" | "receivePresence" | "sendPresence";
|
|
30
30
|
type WorktreeEndpointMiddlewareNext = () => Promise<void>;
|
|
@@ -37,9 +37,9 @@ interface WorktreeEndpointMiddlewareMap {
|
|
|
37
37
|
}
|
|
38
38
|
interface MemberLeftWorktreeUnitEvent {
|
|
39
39
|
readonly worktreeID: string;
|
|
40
|
-
readonly session:
|
|
40
|
+
readonly session: EndpointSession;
|
|
41
41
|
readonly unitID: string;
|
|
42
|
-
readonly reason:
|
|
42
|
+
readonly reason: MemberLeftUnitReason;
|
|
43
43
|
}
|
|
44
44
|
interface WorktreeEndpointEventMap {
|
|
45
45
|
readonly memberLeftUnit: MemberLeftWorktreeUnitEvent;
|
|
@@ -49,14 +49,12 @@ interface WorktreeChangedMessage {
|
|
|
49
49
|
readonly worktree: WorktreeData;
|
|
50
50
|
}
|
|
51
51
|
type EndpointListener<K extends keyof WorktreeEndpointEventMap> = (event: WorktreeEndpointEventMap[K]) => void | Promise<void>;
|
|
52
|
-
declare class UniverCollabWorktreeEndpoint implements
|
|
52
|
+
declare class UniverCollabWorktreeEndpoint implements NodeTransportEndpoint {
|
|
53
53
|
private readonly _service;
|
|
54
54
|
private readonly _options;
|
|
55
55
|
private readonly _middleware;
|
|
56
56
|
private readonly _listeners;
|
|
57
57
|
private readonly _scopedEndpoints;
|
|
58
|
-
private readonly _connectionOwners;
|
|
59
|
-
private readonly _connectionReady;
|
|
60
58
|
private readonly _eventBindings;
|
|
61
59
|
private readonly _eventRooms;
|
|
62
60
|
private readonly _eventQueues;
|
|
@@ -66,18 +64,17 @@ declare class UniverCollabWorktreeEndpoint implements NodeTransportMiddlewareObj
|
|
|
66
64
|
constructor(_service: IUniverCollabWorktreeService, _options: UniverCollabWorktreeEndpointOptions);
|
|
67
65
|
use<K extends WorktreeEndpointMiddlewareAction>(action: K, middleware: WorktreeEndpointMiddlewareMap[K]): Disposable;
|
|
68
66
|
on<K extends keyof WorktreeEndpointEventMap>(event: K, listener: EndpointListener<K>): Disposable;
|
|
69
|
-
|
|
67
|
+
register(router: NodeRouter): void;
|
|
68
|
+
private _handleEventUpgrade;
|
|
70
69
|
dispose(): Promise<void>;
|
|
71
|
-
private
|
|
70
|
+
private _handleTicket;
|
|
72
71
|
private _handleManagement;
|
|
73
|
-
private _handleOpen;
|
|
74
72
|
private _openEventConnection;
|
|
75
73
|
private _scopedEndpoint;
|
|
76
74
|
private _getJoinableWorktree;
|
|
77
75
|
private _enqueueWorktreeChanged;
|
|
78
76
|
private _sendChanged;
|
|
79
77
|
private _removeEventBinding;
|
|
80
|
-
private _waitForConnectionReady;
|
|
81
78
|
private _emit;
|
|
82
79
|
private _requireUser;
|
|
83
80
|
private _writeFailure;
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
const _0x1e270a=_0x4a06;function _0x5221(){const _0x58d707=['1983544GCNogo','527515sZimSk','2xvwhnU','282768xYMCHc','26533910VJZwha','2730750BkSOoJ','20AuODIz','4794783NASGVz','UniverCollabWorktreeEndpoint','36ZwmAqj','1375901rhiUFF'];_0x5221=function(){return _0x58d707;};return _0x5221();}(function(_0x25195c,_0x374ff3){const _0x2ef1f7=_0x4a06,_0x4c6ede=_0x25195c();while(!![]){try{const _0x15d655=parseInt(_0x2ef1f7(0x1e8))/0x1*(parseInt(_0x2ef1f7(0x1eb))/0x2)+parseInt(_0x2ef1f7(0x1ee))/0x3+-parseInt(_0x2ef1f7(0x1ef))/0x4*(parseInt(_0x2ef1f7(0x1ea))/0x5)+-parseInt(_0x2ef1f7(0x1ec))/0x6+parseInt(_0x2ef1f7(0x1e5))/0x7+-parseInt(_0x2ef1f7(0x1e9))/0x8*(-parseInt(_0x2ef1f7(0x1e7))/0x9)+-parseInt(_0x2ef1f7(0x1ed))/0xa;if(_0x15d655===_0x374ff3)break;else _0x4c6ede['push'](_0x4c6ede['shift']());}catch(_0xefd472){_0x4c6ede['push'](_0x4c6ede['shift']());}}}(_0x5221,0xb368a));function _0x4a06(_0x3d2484,_0xa2b67){_0x3d2484=_0x3d2484-0x1e5;const _0x522117=_0x5221();let _0x4a068a=_0x522117[_0x3d2484];return _0x4a068a;}import _0x4fc783 from'./index.cjs';const facadeExport0=_0x4fc783[_0x1e270a(0x1e6)];export{facadeExport0 as UniverCollabWorktreeEndpoint};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@univerjs-pro/collaboration-worktree-endpoint",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.0
|
|
4
|
+
"version": "1.0.0",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -16,13 +16,10 @@
|
|
|
16
16
|
"dist"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@univerjs-pro/collaboration-endpoint": "1.0.0
|
|
20
|
-
"@univerjs-pro/collaboration-service": "1.0.0
|
|
21
|
-
"@univerjs-pro/collaboration-transport-node": "1.0.0
|
|
22
|
-
"@univerjs-pro/collaboration-worktree-service": "1.0.0
|
|
23
|
-
"@univerjs/protocol": "1.0.0
|
|
24
|
-
},
|
|
25
|
-
"publishConfig": {
|
|
26
|
-
"access": "public"
|
|
19
|
+
"@univerjs-pro/collaboration-endpoint": "1.0.0",
|
|
20
|
+
"@univerjs-pro/collaboration-service": "1.0.0",
|
|
21
|
+
"@univerjs-pro/collaboration-transport-node": "1.0.0",
|
|
22
|
+
"@univerjs-pro/collaboration-worktree-service": "1.0.0",
|
|
23
|
+
"@univerjs/protocol": "1.0.0"
|
|
27
24
|
}
|
|
28
|
-
}
|
|
25
|
+
}
|