rhine-var 0.4.10 → 0.5.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 CHANGED
@@ -29,7 +29,7 @@ Try: [https://rv.rhineai.com/examples/counter](https://rv.rhineai.com/examples/c
29
29
 
30
30
  ## Overview
31
31
 
32
- **Document:** [LEARN_zh.md](assets/documents/LEARN_zh.md)
32
+ **Document:** [LEARN.md](assets/documents/LEARN.md)
33
33
 
34
34
  **Github:** [https://github.com/RhineAI-Lab/rhine-var](https://github.com/RhineAI-Lab/rhine-var)
35
35
 
package/README_zh.md CHANGED
@@ -1,216 +1,216 @@
1
- <div align="center">
2
-
3
- # 最简单且强大的多人协同框架 RHINE-VAR
4
-
5
- 莱茵变量 —— 会自己与他人协同的变量 &nbsp; 多人协同应用开发从未如此简单
6
-
7
- [English](README.md) &nbsp; | &nbsp; [中文](README_zh.md)
8
-
9
- <img src='./assets/images/example_counter.png' style="border-radius: 10px"/>
10
-
11
- </div>
12
-
13
- ```typescript jsx
14
- const state = rhineProxy({count: 0}, 'room-0') // Create
15
- function Counter() {
16
- const snap = useRhine(state) // Hook for React
17
- return <div>
18
- <span>{snap.count}</span> // Automatic Update
19
- <button onClick={() => state.count-- }> -1 </button> // Operate Anyway
20
- <button onClick={() => state.count++ }> +1 </button>
21
- </div>
22
- }
23
- ```
24
-
25
- Try: [https://rv.rhineai.com/examples/counter](https://rv.rhineai.com/examples/counter)
26
-
27
- <br/>
28
-
29
- ## 简介
30
-
31
- **Document:** [LEARN_zh.md](assets/documents/LEARN_zh.md)
32
-
33
- **Github:** [https://github.com/RhineAI-Lab/rhine-var](https://github.com/RhineAI-Lab/rhine-var)
34
-
35
- **Npm:** [https://www.npmjs.com/package/rhine-var](https://www.npmjs.com/package/rhine-var)
36
-
37
- <br/>
38
-
39
- ## 为什么选择 RHINE-VAR ?
40
-
41
- <div style="height: 6px"></div>
42
-
43
- ### 简洁高效的语法设计
44
-
45
- RHINE-VAR 借鉴了 Valtio 状态管理库的设计理念,极大地降低了学习成本。开发者可以像操作普通变量一样轻松操控协同数据。
46
-
47
- ### 完备的类型支持
48
-
49
- RHINE-VAR 提供全面的类型提示和类型检查,确保在开发过程中能够获得精确的代码补全和静态分析。这不仅改善了开发体验,还有效降低了潜在的错误风险,特别适用于 TypeScript 项目,提升了代码的安全性和可靠性。
50
-
51
- ### 分布式实时协作算法
52
-
53
- RHINE-VAR 的底层协同算法基于强大的 Yjs 库。通过 CRDT (Conflict-free Replicated Data Type,无冲突复制数据类型) 算法,确保多用户同时使用,甚至离线下使用的最终一致性。
54
-
55
- ### 完全开源
56
-
57
- 这是个完全开源的项目,本库在 Github 上以 Apache-2.0 许可证发布。您可以自由将其用于商业和非商业项目,并且允许对其进行修改和分发,只需要保留原作者的版权声明。
58
-
59
- <br/>
60
- <details>
61
- <summary><b>更多 RHINE-VAR 的优势</b></summary>
62
-
63
- ### 高性能和低带宽需求
64
-
65
- 数据同步和冲突解决机制非常高效,通过 Yjs 的增量更新机制,仅传输必要的数据更改,而非整个文档。这使得它在网络带宽受限的环境中表现良好,减少了不必要的数据传输。
66
-
67
- ### 强大的离线支持
68
-
69
- 即使在离线状态下,用户仍然可以继续使用应用。当重新联机时,所有更改将自动同步,确保数据不会出现丢失或冲突。这对于构建离线优先的应用至关重要。
70
-
71
- ### 几乎没有体积上限
72
-
73
- 它几乎没有体积限制,可以是一个极其复杂且庞大的数据结构,以容纳一个大型项目所需的所有数据。但至少是一个 JavaScript 对象。
74
-
75
- ### 跨平台和框架无关
76
-
77
- RHINE-VAR 支持在多种环境中使用,包括浏览器、Node.js 和其它 JavaScript 环境。此外,它可以与多个前端框架和库 (如 NextJs、React、Vue.js、ProseMirror 等) 集成。
78
-
79
- ### 轻量级且可扩展
80
-
81
- RHINE-VAR 是一个非常轻量的库,核心包仅几 KB,适合各种前端应用。其模块化架构也支持扩展特性,开发者可以根据需要引入或开发自定义模块。
82
-
83
- ### 更友好且完善的事件体系
84
-
85
- RHINE-VAR 提供了丰富的事件订阅监听方式,直观的数据变更事件,更好的支持数据变更的监听和处理。以及提供了对内部深层数据变化的监听,以适用更多场景。
86
-
87
- ### 原生Yjs支持
88
-
89
- RHINE-VAR 提供完好的Yjs原生对象操作支持,更底层更丰富的API支持。直接对Yjs的对象进行操作,也将自动触发 RHINE-VAR 的更新。
90
-
91
- ### 去中心化架构
92
-
93
- 通过去中心化架构,使得协作编辑更具扩展性、更高效且更具容错能力。可通过 P2P 进行数据传输,无需依赖中央服务器(开发中)。
94
-
95
- </details>
96
-
97
- <br/>
98
-
99
- ## Contact Us
100
-
101
- 欢迎加入我们的微信群一起讨论交流,我们期待更多的社区开发者能加入到 RHINE-VAR 的创造中!
102
-
103
- 微信: [FNA-04]() (请备注来源)
104
-
105
- 邮箱: [RhineAILab@gmail.com](rhineailab@gmail.com) & [RhineAI@163.com](RhineAI@163.com)
106
-
107
- <br/>
108
-
109
- ## Install
110
- ```bash
111
- yarn add rhine-var
112
- ```
113
- 如果你的电脑未安装`yarn`, 也可通过 `npm i rhine-var` 安装。或先用 `npm i -g yarn` 安装`yarn`,然后再用上方命令进行安装。
114
-
115
- <br/>
116
-
117
- ## Usage
118
-
119
- ```typescript jsx
120
- const defaultValue = {value: 0}
121
- const url = 'ws://localhost:6600/room-0'
122
-
123
- const state = rhineProxy(defaultValue, url)
124
-
125
- function Counter() {
126
-
127
- const snap = useRhine(state)
128
-
129
- return <div>
130
- <button onClick={() => state.count-- }> -1 </button>
131
- <span>{snap.count}</span>
132
- <button onClick={() => state.count++ }> +1 </button>
133
- </div>
134
- }
135
- ```
136
-
137
- ### Room ID
138
-
139
- 一个房间号对应一个状态变量, 加入到一个房间中的用户会参与到多人协同中。支持使用自己的服务端,甚至其他链接协议。
140
-
141
- ### Default Value
142
-
143
- 当服务端无信息时,将使用 DefaultValue 作为项目默认内容。
144
-
145
- ### rhineProxy
146
-
147
- 用于创建一个 `RhineVar 对象` 它的属性的值会和房间中的其他人共享并同步。
148
-
149
- 你可以像操作 `JavaScript` 中的普通变量一样直接随意操作它。
150
-
151
- 他内部数据结构可以很复杂,但至少需要是 `JavaScript` 中的一个 `object`。
152
-
153
- ### useRhine
154
-
155
- 一个 `React` 的 `Hook` 函数. 它将为 `RhineVariable` 创建一个快照, 用于自动更新页面。
156
-
157
- 当任何人对值做出修改时,它会把最新的值立刻更新到所有人的屏幕上。
158
-
159
- 注意:返回的快照为只读,请勿对其做出操作!快照仅用于在 React 的 XML 中读取数据。其他所有操作(如赋值或订阅等)请操作原 RhineVar 对象。
160
-
161
- <br/>
162
-
163
- #### [点击查看 完整文档 LEARN_zh.md](assets/documents/LEARN_zh.md)
164
-
165
-
166
- <br/>
167
-
168
- ## Server
169
-
170
- 我们提供了一个位于公网的公共服务器,可以用于试用和测试 RHINE-VAR。你可以通过 `wss://rwq.rhineai.com/<room-id>` 连接它。
171
-
172
- 注意,该服务器无法保证安全和性能,并会对大规模使用的用户做出一定限制。
173
-
174
- <br/>
175
-
176
- 本仓库中提供了一个简单的服务器例子,位于本项目中的 `/test/server` 处。 服务端完全兼容所有的 Yjs 的 Websocket 服务器,将来会支持更多。
177
- ```
178
- git clone https://github.com/RhineAI-Lab/rhine-var.git
179
- cd test/server
180
- yarn install
181
- yarn start
182
- ```
183
- 默认运行在 `端口 6600`, 你可以通过连接 `ws://localhost:6600/<room-id>` 连接它,`<room-id>` 可以是任意文本,一个房间号对应一个 `RhineVar 对象`。
184
-
185
- 更多服务端开发信息请参考: [https://docs.yjs.dev/ecosystem/connection-provider/y-websocket](https://docs.yjs.dev/ecosystem/connection-provider/y-websocket)
186
-
187
- <br/>
188
-
189
- ## Develop
190
-
191
- 欢迎参与 RHINE-VAR 库的共同开发。本库内有基本的服务端,和调试用 NextJS 项目,可以满足大部分开发过程基本需求。
192
-
193
-
194
- ### 准备工作 仅初次使用时需执行
195
- ```bash
196
- # 安装依赖
197
- yarn install
198
- # 安装 NextJs 环境调试项目的依赖
199
- yarn run install-next
200
- # 链接本库到 NextJs 环境调试项目
201
- yarn run link-next
202
- ```
203
-
204
- ### 开始调试
205
- ```bash
206
- # 启用 typescript 实时编译
207
- yarn run watch
208
- # 启用临时本地服务端 默认端口6600
209
- yarn run server
210
- # 启动 NextJs 环境调试项目 默认端口6700
211
- yarn run next
212
- # 浏览器将跳转至 http://localhost:6700
213
- ```
214
-
215
- <br/>
216
-
1
+ <div align="center">
2
+
3
+ # 最简单且强大的多人协同框架 RHINE-VAR
4
+
5
+ 莱茵变量 —— 会自己与他人协同的变量 &nbsp; 多人协同应用开发从未如此简单
6
+
7
+ [English](README.md) &nbsp; | &nbsp; [中文](README_zh.md)
8
+
9
+ <img src='./assets/images/example_counter.png' style="border-radius: 10px"/>
10
+
11
+ </div>
12
+
13
+ ```typescript jsx
14
+ const state = rhineProxy({count: 0}, 'room-0') // Create
15
+ function Counter() {
16
+ const snap = useRhine(state) // Hook for React
17
+ return <div>
18
+ <span>{snap.count}</span> // Automatic Update
19
+ <button onClick={() => state.count-- }> -1 </button> // Operate Anyway
20
+ <button onClick={() => state.count++ }> +1 </button>
21
+ </div>
22
+ }
23
+ ```
24
+
25
+ Try: [https://rv.rhineai.com/examples/counter](https://rv.rhineai.com/examples/counter)
26
+
27
+ <br/>
28
+
29
+ ## 简介
30
+
31
+ **Document:** [LEARN_zh.md](assets/documents/LEARN_zh.md)
32
+
33
+ **Github:** [https://github.com/RhineAI-Lab/rhine-var](https://github.com/RhineAI-Lab/rhine-var)
34
+
35
+ **Npm:** [https://www.npmjs.com/package/rhine-var](https://www.npmjs.com/package/rhine-var)
36
+
37
+ <br/>
38
+
39
+ ## 为什么选择 RHINE-VAR ?
40
+
41
+ <div style="height: 6px"></div>
42
+
43
+ ### 简洁高效的语法设计
44
+
45
+ RHINE-VAR 借鉴了 Valtio 状态管理库的设计理念,极大地降低了学习成本。开发者可以像操作普通变量一样轻松操控协同数据。
46
+
47
+ ### 完备的类型支持
48
+
49
+ RHINE-VAR 提供全面的类型提示和类型检查,确保在开发过程中能够获得精确的代码补全和静态分析。这不仅改善了开发体验,还有效降低了潜在的错误风险,特别适用于 TypeScript 项目,提升了代码的安全性和可靠性。
50
+
51
+ ### 分布式实时协作算法
52
+
53
+ RHINE-VAR 的底层协同算法基于强大的 Yjs 库。通过 CRDT (Conflict-free Replicated Data Type,无冲突复制数据类型) 算法,确保多用户同时使用,甚至离线下使用的最终一致性。
54
+
55
+ ### 完全开源
56
+
57
+ 这是个完全开源的项目,本库在 Github 上以 Apache-2.0 许可证发布。您可以自由将其用于商业和非商业项目,并且允许对其进行修改和分发,只需要保留原作者的版权声明。
58
+
59
+ <br/>
60
+ <details>
61
+ <summary><b>更多 RHINE-VAR 的优势</b></summary>
62
+
63
+ ### 高性能和低带宽需求
64
+
65
+ 数据同步和冲突解决机制非常高效,通过 Yjs 的增量更新机制,仅传输必要的数据更改,而非整个文档。这使得它在网络带宽受限的环境中表现良好,减少了不必要的数据传输。
66
+
67
+ ### 强大的离线支持
68
+
69
+ 即使在离线状态下,用户仍然可以继续使用应用。当重新联机时,所有更改将自动同步,确保数据不会出现丢失或冲突。这对于构建离线优先的应用至关重要。
70
+
71
+ ### 几乎没有体积上限
72
+
73
+ 它几乎没有体积限制,可以是一个极其复杂且庞大的数据结构,以容纳一个大型项目所需的所有数据。但至少是一个 JavaScript 对象。
74
+
75
+ ### 跨平台和框架无关
76
+
77
+ RHINE-VAR 支持在多种环境中使用,包括浏览器、Node.js 和其它 JavaScript 环境。此外,它可以与多个前端框架和库 (如 NextJs、React、Vue.js、ProseMirror 等) 集成。
78
+
79
+ ### 轻量级且可扩展
80
+
81
+ RHINE-VAR 是一个非常轻量的库,核心包仅几 KB,适合各种前端应用。其模块化架构也支持扩展特性,开发者可以根据需要引入或开发自定义模块。
82
+
83
+ ### 更友好且完善的事件体系
84
+
85
+ RHINE-VAR 提供了丰富的事件订阅监听方式,直观的数据变更事件,更好的支持数据变更的监听和处理。以及提供了对内部深层数据变化的监听,以适用更多场景。
86
+
87
+ ### 原生Yjs支持
88
+
89
+ RHINE-VAR 提供完好的Yjs原生对象操作支持,更底层更丰富的API支持。直接对Yjs的对象进行操作,也将自动触发 RHINE-VAR 的更新。
90
+
91
+ ### 去中心化架构
92
+
93
+ 通过去中心化架构,使得协作编辑更具扩展性、更高效且更具容错能力。可通过 P2P 进行数据传输,无需依赖中央服务器(开发中)。
94
+
95
+ </details>
96
+
97
+ <br/>
98
+
99
+ ## Contact Us
100
+
101
+ 欢迎加入我们的微信群一起讨论交流,我们期待更多的社区开发者能加入到 RHINE-VAR 的创造中!
102
+
103
+ 微信: [FNA-04]() (请备注来源)
104
+
105
+ 邮箱: [RhineAILab@gmail.com](rhineailab@gmail.com) & [RhineAI@163.com](RhineAI@163.com)
106
+
107
+ <br/>
108
+
109
+ ## Install
110
+ ```bash
111
+ yarn add rhine-var
112
+ ```
113
+ 如果你的电脑未安装`yarn`, 也可通过 `npm i rhine-var` 安装。或先用 `npm i -g yarn` 安装`yarn`,然后再用上方命令进行安装。
114
+
115
+ <br/>
116
+
117
+ ## Usage
118
+
119
+ ```typescript jsx
120
+ const defaultValue = {value: 0}
121
+ const url = 'ws://localhost:6600/room-0'
122
+
123
+ const state = rhineProxy(defaultValue, url)
124
+
125
+ function Counter() {
126
+
127
+ const snap = useRhine(state)
128
+
129
+ return <div>
130
+ <button onClick={() => state.count-- }> -1 </button>
131
+ <span>{snap.count}</span>
132
+ <button onClick={() => state.count++ }> +1 </button>
133
+ </div>
134
+ }
135
+ ```
136
+
137
+ ### Room ID
138
+
139
+ 一个房间号对应一个状态变量, 加入到一个房间中的用户会参与到多人协同中。支持使用自己的服务端,甚至其他链接协议。
140
+
141
+ ### Default Value
142
+
143
+ 当服务端无信息时,将使用 DefaultValue 作为项目默认内容。
144
+
145
+ ### rhineProxy
146
+
147
+ 用于创建一个 `RhineVar 对象` 它的属性的值会和房间中的其他人共享并同步。
148
+
149
+ 你可以像操作 `JavaScript` 中的普通变量一样直接随意操作它。
150
+
151
+ 他内部数据结构可以很复杂,但至少需要是 `JavaScript` 中的一个 `object`。
152
+
153
+ ### useRhine
154
+
155
+ 一个 `React` 的 `Hook` 函数. 它将为 `RhineVariable` 创建一个快照, 用于自动更新页面。
156
+
157
+ 当任何人对值做出修改时,它会把最新的值立刻更新到所有人的屏幕上。
158
+
159
+ 注意:返回的快照为只读,请勿对其做出操作!快照仅用于在 React 的 XML 中读取数据。其他所有操作(如赋值或订阅等)请操作原 RhineVar 对象。
160
+
161
+ <br/>
162
+
163
+ #### [点击查看 完整文档 LEARN_zh.md](assets/documents/LEARN_zh.md)
164
+
165
+
166
+ <br/>
167
+
168
+ ## Server
169
+
170
+ 我们提供了一个位于公网的公共服务器,可以用于试用和测试 RHINE-VAR。你可以通过 `wss://rwq.rhineai.com/<room-id>` 连接它。
171
+
172
+ 注意,该服务器无法保证安全和性能,并会对大规模使用的用户做出一定限制。
173
+
174
+ <br/>
175
+
176
+ 本仓库中提供了一个简单的服务器例子,位于本项目中的 `/test/server` 处。 服务端完全兼容所有的 Yjs 的 Websocket 服务器,将来会支持更多。
177
+ ```
178
+ git clone https://github.com/RhineAI-Lab/rhine-var.git
179
+ cd test/server
180
+ yarn install
181
+ yarn start
182
+ ```
183
+ 默认运行在 `端口 6600`, 你可以通过连接 `ws://localhost:6600/<room-id>` 连接它,`<room-id>` 可以是任意文本,一个房间号对应一个 `RhineVar 对象`。
184
+
185
+ 更多服务端开发信息请参考: [https://docs.yjs.dev/ecosystem/connection-provider/y-websocket](https://docs.yjs.dev/ecosystem/connection-provider/y-websocket)
186
+
187
+ <br/>
188
+
189
+ ## Develop
190
+
191
+ 欢迎参与 RHINE-VAR 库的共同开发。本库内有基本的服务端,和调试用 NextJS 项目,可以满足大部分开发过程基本需求。
192
+
193
+
194
+ ### 准备工作 仅初次使用时需执行
195
+ ```bash
196
+ # 安装依赖
197
+ yarn install
198
+ # 安装 NextJs 环境调试项目的依赖
199
+ yarn run install-next
200
+ # 链接本库到 NextJs 环境调试项目
201
+ yarn run link-next
202
+ ```
203
+
204
+ ### 开始调试
205
+ ```bash
206
+ # 启用 typescript 实时编译
207
+ yarn run watch
208
+ # 启用临时本地服务端 默认端口6600
209
+ yarn run server
210
+ # 启动 NextJs 环境调试项目 默认端口6700
211
+ yarn run next
212
+ # 浏览器将跳转至 http://localhost:6700
213
+ ```
214
+
215
+ <br/>
216
+
@@ -0,0 +1,28 @@
1
+ import { Doc as YDoc, Map as YMap } from "yjs";
2
+ import { WebsocketProvider } from "y-websocket";
3
+ import { ConnectorStatus } from "./ConnectorStatus";
4
+ import { Native } from "../native/Native";
5
+ import { SyncedCallback } from "../event/Callback";
6
+ export default class WebsocketConnector {
7
+ static STATE_KEY: string;
8
+ yDoc: YDoc;
9
+ yBaseMap: YMap<any>;
10
+ url: string;
11
+ clientId: number;
12
+ synced: boolean;
13
+ provider: WebsocketProvider | null;
14
+ websocketStatus: ConnectorStatus;
15
+ private syncedSubscribers;
16
+ subscribeSynced(callback: SyncedCallback): () => void;
17
+ unsubscribeSynced(callback: SyncedCallback): void;
18
+ unsubscribeAllSynced(): void;
19
+ emitSynced(synced: boolean): void;
20
+ afterSynced(callback: () => void): void;
21
+ waitSynced(): Promise<void>;
22
+ constructor(url?: string);
23
+ bind(defaultValue: Native, overwrite?: boolean): any;
24
+ connect(url: string): Promise<void>;
25
+ disconnect(): Promise<void>;
26
+ }
27
+ export declare function websocketRhineConnect(url: string): WebsocketConnector;
28
+ //# sourceMappingURL=WebsocketConnector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebsocketConnector.d.ts","sourceRoot":"","sources":["../../../src/core/connector/WebsocketConnector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,IAAI,IAAI,EAAE,GAAG,IAAI,IAAI,EAAC,MAAM,KAAK,CAAC;AAC7C,OAAO,EAAC,iBAAiB,EAAC,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAC,eAAe,EAAC,0BAAyC;AAEjE,OAAO,EAAC,MAAM,EAAC,yBAA6B;AAC5C,OAAO,EAAC,cAAc,EAAC,0BAA8B;AAErD,MAAM,CAAC,OAAO,OAAO,kBAAkB;IAErC,MAAM,CAAC,SAAS,SAAU;IAE1B,IAAI,EAAE,IAAI,CAAA;IACV,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAA;IACnB,GAAG,EAAE,MAAM,CAAK;IAEhB,QAAQ,SAAK;IACb,MAAM,UAAQ;IAEd,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAO;IACzC,eAAe,EAAE,eAAe,CAA+B;IAG/D,OAAO,CAAC,iBAAiB,CAAuB;IAChD,eAAe,CAAC,QAAQ,EAAE,cAAc;IAIxC,iBAAiB,CAAC,QAAQ,EAAE,cAAc;IAG1C,oBAAoB;IAGpB,UAAU,CAAC,MAAM,EAAE,OAAO;IAI1B,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI;IAahC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;gBAOf,GAAG,SAAK;IAMpB,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,GAAE,OAAe;IAc/C,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4CnC,UAAU;CAYjB;AAGD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,sBAMhD"}
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.websocketRhineConnect = websocketRhineConnect;
4
+ const yjs_1 = require("yjs");
5
+ const y_websocket_1 = require("y-websocket");
6
+ const ConnectorStatus_1 = require("./ConnectorStatus");
7
+ const Logger_1 = require("../utils/Logger");
8
+ class WebsocketConnector {
9
+ subscribeSynced(callback) {
10
+ this.syncedSubscribers.push(callback);
11
+ return () => this.unsubscribeSynced(callback);
12
+ }
13
+ unsubscribeSynced(callback) {
14
+ this.syncedSubscribers = this.syncedSubscribers.filter(subscriber => subscriber !== callback);
15
+ }
16
+ unsubscribeAllSynced() {
17
+ this.syncedSubscribers = [];
18
+ }
19
+ emitSynced(synced) {
20
+ this.syncedSubscribers.forEach(subscriber => subscriber(synced));
21
+ }
22
+ afterSynced(callback) {
23
+ if (this.synced) {
24
+ callback();
25
+ }
26
+ else {
27
+ const subscriber = (synced) => {
28
+ if (synced) {
29
+ this.unsubscribeSynced(subscriber);
30
+ callback();
31
+ }
32
+ };
33
+ this.subscribeSynced(subscriber);
34
+ }
35
+ }
36
+ waitSynced() {
37
+ return new Promise((resolve) => {
38
+ this.afterSynced(resolve);
39
+ });
40
+ }
41
+ constructor(url = '') {
42
+ this.url = '';
43
+ this.clientId = -1;
44
+ this.synced = false;
45
+ this.provider = null;
46
+ this.websocketStatus = ConnectorStatus_1.ConnectorStatus.DISCONNECTED;
47
+ this.syncedSubscribers = [];
48
+ this.yDoc = new yjs_1.Doc();
49
+ this.yBaseMap = this.yDoc.getMap();
50
+ url && this.connect(url);
51
+ }
52
+ bind(defaultValue, overwrite = false) {
53
+ if (this.synced) {
54
+ if (!overwrite && this.yBaseMap.has(WebsocketConnector.STATE_KEY)) {
55
+ return this.yBaseMap.get(WebsocketConnector.STATE_KEY);
56
+ }
57
+ this.yBaseMap.set(WebsocketConnector.STATE_KEY, defaultValue);
58
+ return defaultValue;
59
+ }
60
+ else {
61
+ const tempMap = new yjs_1.Doc().getMap();
62
+ tempMap.set(WebsocketConnector.STATE_KEY, defaultValue);
63
+ return defaultValue;
64
+ }
65
+ }
66
+ async connect(url) {
67
+ this.url = url;
68
+ let li = this.url.lastIndexOf('/');
69
+ if (li == -1 || li == this.url.length - 1 || !this.url.startsWith('ws')) {
70
+ console.error('UnSupport URL for Connect Room');
71
+ return;
72
+ }
73
+ return new Promise((resolve, reject) => {
74
+ this.provider = new y_websocket_1.WebsocketProvider(this.url.slice(0, li), this.url.slice(li + 1), this.yDoc);
75
+ this.provider.shouldConnect = true;
76
+ this.provider.on('status', (event) => {
77
+ this.websocketStatus = event.status;
78
+ (0, Logger_1.log)('WebsocketRhineConnector.event status:', event.status);
79
+ });
80
+ this.provider.on('sync', (synced) => {
81
+ (0, Logger_1.log)('WebsocketRhineConnector.event sync:', synced);
82
+ if (synced) {
83
+ this.synced = true;
84
+ this.clientId = this.yDoc.clientID;
85
+ this.emitSynced(synced);
86
+ resolve();
87
+ }
88
+ });
89
+ this.provider.on('connection-close', (e) => {
90
+ this.websocketStatus = ConnectorStatus_1.ConnectorStatus.DISCONNECTED;
91
+ (0, Logger_1.log)('WebsocketRhineConnector.event connection-close:', e);
92
+ });
93
+ this.provider.on('connection-error', (error) => {
94
+ this.websocketStatus = ConnectorStatus_1.ConnectorStatus.DISCONNECTED;
95
+ (0, Logger_1.log)('WebsocketRhineConnector.event connection-error:', error);
96
+ });
97
+ });
98
+ }
99
+ async disconnect() {
100
+ throw new Error('Disconnecting and switching connections are not supported at the moment.');
101
+ /*
102
+ if (this.provider) {
103
+ this.provider.disconnect()
104
+ }
105
+ this.provider = null
106
+ this.synced = false
107
+ this.websocketStatus = ConnectorStatus.DISCONNECTED
108
+ */
109
+ }
110
+ }
111
+ WebsocketConnector.STATE_KEY = 'state';
112
+ exports.default = WebsocketConnector;
113
+ function websocketRhineConnect(url) {
114
+ const connector = new WebsocketConnector();
115
+ if (typeof window !== 'undefined') {
116
+ connector.connect(url);
117
+ }
118
+ return connector;
119
+ }
@@ -2,7 +2,7 @@ import { Doc as YDoc, Map as YMap } from "yjs";
2
2
  import { WebsocketProvider } from "y-websocket";
3
3
  import { ConnectorStatus } from "./ConnectorStatus";
4
4
  import { Native } from "../native/Native";
5
- export type SyncedListener = (synced: boolean) => void;
5
+ import { SyncedCallback } from "../event/Callback";
6
6
  export default class WebsocketRhineConnector {
7
7
  static STATE_KEY: string;
8
8
  yDoc: YDoc;
@@ -12,9 +12,10 @@ export default class WebsocketRhineConnector {
12
12
  synced: boolean;
13
13
  provider: WebsocketProvider | null;
14
14
  websocketStatus: ConnectorStatus;
15
- syncedListeners: SyncedListener[];
16
- addSyncedListener(listener: SyncedListener): void;
17
- removeSyncedListener(listener: SyncedListener): void;
15
+ private syncedSubscribers;
16
+ subscribeSynced(callback: SyncedCallback): () => void;
17
+ unsubscribeSynced(callback: SyncedCallback): void;
18
+ unsubscribeAllSynced(): void;
18
19
  emitSynced(synced: boolean): void;
19
20
  afterSynced(callback: () => void): void;
20
21
  waitSynced(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"WebsocketRhineConnector.d.ts","sourceRoot":"","sources":["../../../src/core/connector/WebsocketRhineConnector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,IAAI,IAAI,EAAE,GAAG,IAAI,IAAI,EAAC,MAAM,KAAK,CAAC;AAC7C,OAAO,EAAC,iBAAiB,EAAC,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAC,eAAe,EAAC,0BAAyC;AAEjE,OAAO,EAAC,MAAM,EAAC,yBAA6B;AAE5C,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAA;AAEtD,MAAM,CAAC,OAAO,OAAO,uBAAuB;IAE1C,MAAM,CAAC,SAAS,SAAU;IAE1B,IAAI,EAAE,IAAI,CAAA;IACV,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAA;IACnB,GAAG,EAAE,MAAM,CAAK;IAEhB,QAAQ,SAAK;IACb,MAAM,UAAQ;IAEd,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAO;IACzC,eAAe,EAAE,eAAe,CAA+B;IAG/D,eAAe,EAAE,cAAc,EAAE,CAAK;IACtC,iBAAiB,CAAC,QAAQ,EAAE,cAAc;IAG1C,oBAAoB,CAAC,QAAQ,EAAE,cAAc;IAG7C,UAAU,CAAC,MAAM,EAAE,OAAO;IAI1B,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI;IAahC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;gBAOf,GAAG,SAAK;IAMpB,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,GAAE,OAAe;IAc/C,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4CnC,UAAU;CAYjB;AAGD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,2BAMhD"}
1
+ {"version":3,"file":"WebsocketRhineConnector.d.ts","sourceRoot":"","sources":["../../../src/core/connector/WebsocketRhineConnector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,IAAI,IAAI,EAAE,GAAG,IAAI,IAAI,EAAC,MAAM,KAAK,CAAC;AAC7C,OAAO,EAAC,iBAAiB,EAAC,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAC,eAAe,EAAC,0BAAyC;AAEjE,OAAO,EAAC,MAAM,EAAC,yBAA6B;AAC5C,OAAO,EAAC,cAAc,EAAC,0BAA8B;AAErD,MAAM,CAAC,OAAO,OAAO,uBAAuB;IAE1C,MAAM,CAAC,SAAS,SAAU;IAE1B,IAAI,EAAE,IAAI,CAAA;IACV,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAA;IACnB,GAAG,EAAE,MAAM,CAAK;IAEhB,QAAQ,SAAK;IACb,MAAM,UAAQ;IAEd,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAO;IACzC,eAAe,EAAE,eAAe,CAA+B;IAG/D,OAAO,CAAC,iBAAiB,CAAuB;IAChD,eAAe,CAAC,QAAQ,EAAE,cAAc;IAIxC,iBAAiB,CAAC,QAAQ,EAAE,cAAc;IAG1C,oBAAoB;IAGpB,UAAU,CAAC,MAAM,EAAE,OAAO;IAI1B,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI;IAahC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;gBAOf,GAAG,SAAK;IAMpB,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,GAAE,OAAe;IAc/C,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4CnC,UAAU;CAYjB;AAGD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,2BAMhD"}
@@ -6,27 +6,31 @@ const y_websocket_1 = require("y-websocket");
6
6
  const ConnectorStatus_1 = require("./ConnectorStatus");
7
7
  const Logger_1 = require("../utils/Logger");
8
8
  class WebsocketRhineConnector {
9
- addSyncedListener(listener) {
10
- this.syncedListeners.push(listener);
9
+ subscribeSynced(callback) {
10
+ this.syncedSubscribers.push(callback);
11
+ return () => this.unsubscribeSynced(callback);
11
12
  }
12
- removeSyncedListener(listener) {
13
- this.syncedListeners = this.syncedListeners.filter(l => l !== listener);
13
+ unsubscribeSynced(callback) {
14
+ this.syncedSubscribers = this.syncedSubscribers.filter(subscriber => subscriber !== callback);
15
+ }
16
+ unsubscribeAllSynced() {
17
+ this.syncedSubscribers = [];
14
18
  }
15
19
  emitSynced(synced) {
16
- this.syncedListeners.forEach(listener => listener(synced));
20
+ this.syncedSubscribers.forEach(subscriber => subscriber(synced));
17
21
  }
18
22
  afterSynced(callback) {
19
23
  if (this.synced) {
20
24
  callback();
21
25
  }
22
26
  else {
23
- const listener = (synced) => {
27
+ const subscriber = (synced) => {
24
28
  if (synced) {
25
- this.removeSyncedListener(listener);
29
+ this.unsubscribeSynced(subscriber);
26
30
  callback();
27
31
  }
28
32
  };
29
- this.addSyncedListener(listener);
33
+ this.subscribeSynced(subscriber);
30
34
  }
31
35
  }
32
36
  waitSynced() {
@@ -40,7 +44,7 @@ class WebsocketRhineConnector {
40
44
  this.synced = false;
41
45
  this.provider = null;
42
46
  this.websocketStatus = ConnectorStatus_1.ConnectorStatus.DISCONNECTED;
43
- this.syncedListeners = [];
47
+ this.syncedSubscribers = [];
44
48
  this.yDoc = new yjs_1.Doc();
45
49
  this.yBaseMap = this.yDoc.getMap();
46
50
  url && this.connect(url);
@@ -4,4 +4,5 @@ import { YPath } from "../native/Native";
4
4
  import { ProxiedRhineVarItem } from "../proxy/ProxiedRhineVar";
5
5
  export type Callback<T> = (key: keyof T, value: T[keyof T] | ProxiedRhineVarItem<T[keyof T]>, oldValue: T[keyof T], type: ChangeType, nativeEvent: YMapEvent<any> | YArrayEvent<any>, nativeTransaction: Transaction) => void;
6
6
  export type DeepCallback<T> = (path: YPath, value: any | ProxiedRhineVarItem<any>, oldValue: any, type: ChangeType, nativeEvent: YMapEvent<any> | YArrayEvent<any>, nativeTransaction: Transaction) => void;
7
+ export type SyncedCallback = (synced: boolean) => void;
7
8
  //# sourceMappingURL=Callback.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Callback.d.ts","sourceRoot":"","sources":["../../../src/core/event/Callback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,qBAAgC;AACnD,OAAO,EAAC,WAAW,EAAE,WAAW,EAAE,SAAS,EAAC,MAAM,KAAK,CAAC;AACxD,OAAO,EAAS,KAAK,EAAC,yBAA6B;AACnD,OAAO,EAAC,mBAAmB,EAAC,iCAAqC;AAGjE,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CACxB,GAAG,EAAE,MAAM,CAAC,EACZ,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EACnD,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EACpB,IAAI,EAAE,UAAU,EAChB,WAAW,EAAE,SAAS,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,EAC9C,iBAAiB,EAAE,WAAW,KAC3B,IAAI,CAAA;AAET,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAC5B,IAAI,EAAE,KAAK,EACX,KAAK,EAAE,GAAG,GAAG,mBAAmB,CAAC,GAAG,CAAC,EACrC,QAAQ,EAAE,GAAG,EACb,IAAI,EAAE,UAAU,EAChB,WAAW,EAAE,SAAS,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,EAC9C,iBAAiB,EAAE,WAAW,KAC3B,IAAI,CAAA"}
1
+ {"version":3,"file":"Callback.d.ts","sourceRoot":"","sources":["../../../src/core/event/Callback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,qBAAgC;AACnD,OAAO,EAAC,WAAW,EAAE,WAAW,EAAE,SAAS,EAAC,MAAM,KAAK,CAAC;AACxD,OAAO,EAAS,KAAK,EAAC,yBAA6B;AACnD,OAAO,EAAC,mBAAmB,EAAC,iCAAqC;AAGjE,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CACxB,GAAG,EAAE,MAAM,CAAC,EACZ,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EACnD,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EACpB,IAAI,EAAE,UAAU,EAChB,WAAW,EAAE,SAAS,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,EAC9C,iBAAiB,EAAE,WAAW,KAC3B,IAAI,CAAA;AAET,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAC5B,IAAI,EAAE,KAAK,EACX,KAAK,EAAE,GAAG,GAAG,mBAAmB,CAAC,GAAG,CAAC,EACrC,QAAQ,EAAE,GAAG,EACb,IAAI,EAAE,UAAU,EAChB,WAAW,EAAE,SAAS,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,EAC9C,iBAAiB,EAAE,WAAW,KAC3B,IAAI,CAAA;AAET,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAA"}
@@ -1,10 +1,10 @@
1
- import WebsocketRhineConnector from "../connector/WebsocketRhineConnector";
1
+ import WebsocketConnector from "../connector/WebsocketConnector";
2
2
  import RhineVarItem from "./RhineVarItem";
3
3
  import { ProxiedRhineVar, ProxiedRhineVarItem } from "./ProxiedRhineVar";
4
4
  import { Native } from "../native/Native";
5
5
  import RhineVar from "./RhineVar";
6
6
  export declare const PROTOCOL_LIST: string[];
7
7
  export declare const DEFAULT_PUBLIC_URL = "wss://rpw.rhineai.com/";
8
- export declare function rhineProxy<T extends object>(defaultValue: T | Native, connector: WebsocketRhineConnector | string | number, overwrite?: boolean | number): ProxiedRhineVar<T>;
8
+ export declare function rhineProxy<T extends object>(defaultValue: T | Native, connector: WebsocketConnector | string | number, overwrite?: boolean | number): ProxiedRhineVar<T>;
9
9
  export declare function rhineProxyItem<T extends object>(data: T | Native, parent?: RhineVar<any> | RhineVarItem<any> | null): ProxiedRhineVarItem<T> | ProxiedRhineVar<T>;
10
10
  //# sourceMappingURL=Proxy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Proxy.d.ts","sourceRoot":"","sources":["../../../src/core/proxy/Proxy.ts"],"names":[],"mappings":"AACA,OAAO,uBAAgD,6CAAiD;AACxG,OAAO,YAA+C,uBAAkC;AAIxF,OAAO,EAAC,eAAe,EAAE,mBAAmB,EAAC,0BAAqC;AAClF,OAAO,EAAC,MAAM,EAAC,yBAA6B;AAS5C,OAAO,QAAQ,mBAA8B;AAG7C,eAAO,MAAM,aAAa,UAAsB,CAAA;AAChD,eAAO,MAAM,kBAAkB,2BAA2B,CAAA;AAG1D,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EACzC,YAAY,EAAE,CAAC,GAAG,MAAM,EACxB,SAAS,EAAE,uBAAuB,GAAG,MAAM,GAAG,MAAM,EACpD,SAAS,GAAE,OAAO,GAAG,MAAc,GAClC,eAAe,CAAC,CAAC,CAAC,CA+CpB;AAGD,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAC7C,IAAI,EAAE,CAAC,GAAG,MAAM,EAChB,MAAM,GAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,IAAW,GACtD,mBAAmB,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CA2F7C"}
1
+ {"version":3,"file":"Proxy.d.ts","sourceRoot":"","sources":["../../../src/core/proxy/Proxy.ts"],"names":[],"mappings":"AACA,OAAO,kBAA2C,wCAA4C;AAC9F,OAAO,YAA+C,uBAAkC;AAIxF,OAAO,EAAC,eAAe,EAAE,mBAAmB,EAAC,0BAAqC;AAClF,OAAO,EAAC,MAAM,EAAC,yBAA6B;AAS5C,OAAO,QAAQ,mBAA8B;AAG7C,eAAO,MAAM,aAAa,UAAsB,CAAA;AAChD,eAAO,MAAM,kBAAkB,2BAA2B,CAAA;AAG1D,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EACzC,YAAY,EAAE,CAAC,GAAG,MAAM,EACxB,SAAS,EAAE,kBAAkB,GAAG,MAAM,GAAG,MAAM,EAC/C,SAAS,GAAE,OAAO,GAAG,MAAc,GAClC,eAAe,CAAC,CAAC,CAAC,CA+CpB;AAGD,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAC7C,IAAI,EAAE,CAAC,GAAG,MAAM,EAChB,MAAM,GAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,IAAW,GACtD,mBAAmB,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CA2F7C"}
@@ -30,7 +30,7 @@ exports.DEFAULT_PUBLIC_URL = exports.PROTOCOL_LIST = void 0;
30
30
  exports.rhineProxy = rhineProxy;
31
31
  exports.rhineProxyItem = rhineProxyItem;
32
32
  const yjs_1 = require("yjs");
33
- const WebsocketRhineConnector_1 = __importStar(require("../connector/WebsocketRhineConnector"));
33
+ const WebsocketConnector_1 = __importStar(require("../connector/WebsocketConnector"));
34
34
  const RhineVarItem_1 = __importStar(require("./RhineVarItem"));
35
35
  const DataUtils_1 = require("../utils/DataUtils");
36
36
  const Logger_1 = require("../utils/Logger");
@@ -42,11 +42,11 @@ exports.DEFAULT_PUBLIC_URL = 'wss://rpw.rhineai.com/';
42
42
  function rhineProxy(defaultValue, connector, overwrite = false) {
43
43
  let target = (0, DataUtils_1.ensureNative)(defaultValue);
44
44
  if (connector) {
45
- if (!(connector instanceof WebsocketRhineConnector_1.default)) {
45
+ if (!(connector instanceof WebsocketConnector_1.default)) {
46
46
  if (exports.PROTOCOL_LIST.every(protocol => !(String(connector)).startsWith(protocol))) {
47
47
  connector = exports.DEFAULT_PUBLIC_URL + connector;
48
48
  }
49
- connector = (0, WebsocketRhineConnector_1.websocketRhineConnect)(String(connector));
49
+ connector = (0, WebsocketConnector_1.websocketRhineConnect)(String(connector));
50
50
  }
51
51
  target = connector.bind(target, Boolean(overwrite));
52
52
  }
@@ -54,17 +54,17 @@ function rhineProxy(defaultValue, connector, overwrite = false) {
54
54
  const object = rhineProxyItem(target);
55
55
  object.connector = connector;
56
56
  if (connector && !connector.synced) {
57
- connector.addSyncedListener((synced) => {
57
+ connector.subscribeSynced((synced) => {
58
58
  if (synced) {
59
59
  let syncedValue = target.clone();
60
- if (!overwrite && connector.yBaseMap.has(WebsocketRhineConnector_1.default.STATE_KEY)) {
61
- syncedValue = connector.yBaseMap.get(WebsocketRhineConnector_1.default.STATE_KEY);
60
+ if (!overwrite && connector.yBaseMap.has(WebsocketConnector_1.default.STATE_KEY)) {
61
+ syncedValue = connector.yBaseMap.get(WebsocketConnector_1.default.STATE_KEY);
62
62
  object.native.forEach((value, key) => {
63
63
  Reflect.deleteProperty(object.origin, key);
64
64
  });
65
- object.unobserve();
65
+ Reflect.get(object, 'unobserve').call(object);
66
66
  object.native = syncedValue;
67
- object.observe();
67
+ Reflect.get(object, 'observe').call(object);
68
68
  (0, Logger_1.log)('Proxy.synced: Update synced native');
69
69
  syncedValue.forEach((value, key) => {
70
70
  if ((0, NativeUtils_1.isNative)(value)) {
@@ -76,7 +76,7 @@ function rhineProxy(defaultValue, connector, overwrite = false) {
76
76
  });
77
77
  }
78
78
  else {
79
- connector.yBaseMap.set(WebsocketRhineConnector_1.default.STATE_KEY, syncedValue);
79
+ connector.yBaseMap.set(WebsocketConnector_1.default.STATE_KEY, syncedValue);
80
80
  }
81
81
  }
82
82
  });
@@ -166,6 +166,6 @@ function rhineProxyItem(data, parent = null) {
166
166
  },
167
167
  getOwnPropertyDescriptor: proxyGetOwnPropertyDescriptor,
168
168
  };
169
- object.observe();
169
+ Reflect.get(object, 'observe').call(object);
170
170
  return new Proxy(object, handler);
171
171
  }
@@ -1,7 +1,7 @@
1
1
  import RhineVarItem from "./RhineVarItem";
2
- import WebsocketRhineConnector from "../connector/WebsocketRhineConnector";
2
+ import WebsocketConnector from "../connector/WebsocketConnector";
3
3
  export default class RhineVar<T> extends RhineVarItem<T> {
4
- connector: WebsocketRhineConnector | null;
4
+ connector: WebsocketConnector | null;
5
5
  isRoot(): boolean;
6
6
  root(): RhineVar<any>;
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"RhineVar.d.ts","sourceRoot":"","sources":["../../../src/core/proxy/RhineVar.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,uBAAkC;AACrD,OAAO,uBAAuB,6CAAiD;AAE/E,MAAM,CAAC,OAAO,OAAO,QAAQ,CAAC,CAAC,CAAE,SAAQ,YAAY,CAAC,CAAC,CAAC;IAEtD,SAAS,EAAE,uBAAuB,GAAG,IAAI,CAAO;IAEhD,MAAM,IAAI,OAAO;IAIjB,IAAI,IAAI,QAAQ,CAAC,GAAG,CAAC;CAItB"}
1
+ {"version":3,"file":"RhineVar.d.ts","sourceRoot":"","sources":["../../../src/core/proxy/RhineVar.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,uBAAkC;AACrD,OAAO,kBAAkB,wCAA4C;AAErE,MAAM,CAAC,OAAO,OAAO,QAAQ,CAAC,CAAC,CAAE,SAAQ,YAAY,CAAC,CAAC,CAAC;IAEtD,SAAS,EAAE,kBAAkB,GAAG,IAAI,CAAO;IAE3C,MAAM,IAAI,OAAO;IAIjB,IAAI,IAAI,QAAQ,CAAC,GAAG,CAAC;CAItB"}
@@ -1,9 +1,10 @@
1
1
  import { Transaction, YArrayEvent, YMapEvent } from "yjs";
2
2
  import { Native, YPath } from "../native/Native";
3
3
  import { ChangeType } from "../event/ChangeType";
4
- import { Callback, DeepCallback } from "../event/Callback";
4
+ import { Callback, DeepCallback, SyncedCallback } from "../event/Callback";
5
5
  import { StoredRhineVarItem } from "./ProxiedRhineVar";
6
6
  import RhineVar from "./RhineVar";
7
+ import WebsocketConnector from "../connector/WebsocketConnector";
7
8
  export default class RhineVarItem<T> {
8
9
  native: Native;
9
10
  parent: RhineVar<any> | RhineVarItem<any> | null;
@@ -11,11 +12,17 @@ export default class RhineVarItem<T> {
11
12
  constructor(native: Native, parent?: RhineVar<any> | RhineVarItem<any> | null, origin?: StoredRhineVarItem<T>);
12
13
  isRoot(): boolean;
13
14
  root(): RhineVar<any>;
15
+ getConnector(): WebsocketConnector | null;
14
16
  afterSynced(callback: () => void): void;
15
17
  waitSynced(): Promise<unknown>;
16
18
  json(): T;
17
19
  frozenJson(): T;
18
- toString(): string;
20
+ string(indent?: number): string;
21
+ private syncedSubscribers;
22
+ subscribeSynced(callback: SyncedCallback): () => void;
23
+ unsubscribeSynced(callback: SyncedCallback): void;
24
+ unsubscribeAllSynced(): void;
25
+ private emitSynced;
19
26
  private subscribers;
20
27
  subscribe(callback: Callback<T>): () => void;
21
28
  unsubscribe(callback: Callback<T>): void;
@@ -30,9 +37,10 @@ export default class RhineVarItem<T> {
30
37
  unsubscribeDeep(callback: DeepCallback<T>): void;
31
38
  unsubscribeAllDeep(): void;
32
39
  emitDeep(path: YPath, value: any, oldValue: any, type: ChangeType, nativeEvent: YMapEvent<any> | YArrayEvent<any>, nativeTransaction: Transaction): undefined;
33
- observer: (event: YMapEvent<any> | YArrayEvent<any>, transaction: Transaction) => void;
34
- observe(): void;
35
- unobserve(): void;
40
+ private observer;
41
+ private syncedObserver;
42
+ private observe;
43
+ private unobserve;
36
44
  }
37
45
  export declare const RHINE_VAR_PREDEFINED_PROPERTIES: Set<string | symbol>;
38
46
  //# sourceMappingURL=RhineVarItem.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RhineVarItem.d.ts","sourceRoot":"","sources":["../../../src/core/proxy/RhineVarItem.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,WAAW,EAAE,WAAW,EAAE,SAAS,EAAC,MAAM,KAAK,CAAC;AAItF,OAAO,EAAC,MAAM,EAAE,KAAK,EAAC,yBAA6B;AACnD,OAAO,EAAC,UAAU,EAAC,4BAAgC;AACnD,OAAO,EAAC,QAAQ,EAAE,YAAY,EAAC,0BAA8B;AAC7D,OAAO,EAAC,kBAAkB,EAAC,0BAAqC;AAChE,OAAO,QAAQ,mBAA8B;AAG7C,MAAM,CAAC,OAAO,OAAO,YAAY,CAAC,CAAC;IAGxB,MAAM,EAAE,MAAM;IACd,MAAM,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,IAAI;IAChD,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC;gBAF7B,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,IAAW,EACvD,MAAM,GAAE,kBAAkB,CAAC,CAAC,CAAe;IAGpD,MAAM,IAAI,OAAO;IAIjB,IAAI,IAAI,QAAQ,CAAC,GAAG,CAAC;IAKrB,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI;IAO1B,UAAU;IAOhB,IAAI,IAAI,CAAC;IAIT,UAAU,IAAI,CAAC;IAwCf,QAAQ;IAKR,OAAO,CAAC,WAAW,CAAoB;IACvC,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAI5C,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IAGjC,cAAc;IAId,OAAO,CAAC,cAAc,CAAyC;IAC/D,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAO7D,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IAKpC,iBAAiB;IAIjB,OAAO,CAAC,IAAI;IAQZ,OAAO,CAAC,eAAe,CAAwB;IAC/C,aAAa,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAIpD,eAAe,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC;IAGzC,kBAAkB;IAIlB,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,EAAE,iBAAiB,EAAE,WAAW;IAgBjJ,QAAQ,UAAW,SAAS,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,eAAe,WAAW,UAAO;IAGrF,OAAO;IAsFP,SAAS;CAKV;AAGD,eAAO,MAAM,+BAA+B,sBAkC1C,CAAA"}
1
+ {"version":3,"file":"RhineVarItem.d.ts","sourceRoot":"","sources":["../../../src/core/proxy/RhineVarItem.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,WAAW,EAAE,WAAW,EAAE,SAAS,EAAC,MAAM,KAAK,CAAC;AAItF,OAAO,EAAC,MAAM,EAAE,KAAK,EAAC,yBAA6B;AACnD,OAAO,EAAC,UAAU,EAAC,4BAAgC;AACnD,OAAO,EAAC,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAC,0BAA8B;AAC7E,OAAO,EAAC,kBAAkB,EAAC,0BAAqC;AAChE,OAAO,QAAQ,mBAA8B;AAC7C,OAAO,kBAAkB,wCAA4C;AAGrE,MAAM,CAAC,OAAO,OAAO,YAAY,CAAC,CAAC;IAGxB,MAAM,EAAE,MAAM;IACd,MAAM,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,IAAI;IAChD,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC;gBAF7B,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,IAAW,EACvD,MAAM,GAAE,kBAAkB,CAAC,CAAC,CAAe;IAGpD,MAAM,IAAI,OAAO;IAIjB,IAAI,IAAI,QAAQ,CAAC,GAAG,CAAC;IAIrB,YAAY,IAAI,kBAAkB,GAAG,IAAI;IAKzC,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI;IAO1B,UAAU;IAOhB,IAAI,IAAI,CAAC;IAIT,UAAU,IAAI,CAAC;IAwCf,MAAM,CAAC,MAAM,SAAI;IAIjB,OAAO,CAAC,iBAAiB,CAAuB;IAChD,eAAe,CAAC,QAAQ,EAAE,cAAc;IAIxC,iBAAiB,CAAC,QAAQ,EAAE,cAAc;IAG1C,oBAAoB;IAIpB,OAAO,CAAC,UAAU;IAKlB,OAAO,CAAC,WAAW,CAAoB;IACvC,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAI5C,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IAGjC,cAAc;IAId,OAAO,CAAC,cAAc,CAAyC;IAC/D,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAO7D,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IAKpC,iBAAiB;IAIjB,OAAO,CAAC,IAAI;IAQZ,OAAO,CAAC,eAAe,CAAwB;IAC/C,aAAa,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAIpD,eAAe,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC;IAGzC,kBAAkB;IAIlB,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,EAAE,iBAAiB,EAAE,WAAW;IAgBjJ,OAAO,CAAC,QAAQ,CAA6E;IAC7F,OAAO,CAAC,cAAc,CAA0C;IAGhE,OAAO,CAAC,OAAO;IA2Ff,OAAO,CAAC,SAAS;CAQlB;AAGD,eAAO,MAAM,+BAA+B,sBAyC1C,CAAA"}
@@ -11,10 +11,12 @@ class RhineVarItem {
11
11
  this.native = native;
12
12
  this.parent = parent;
13
13
  this.origin = origin;
14
+ this.syncedSubscribers = [];
14
15
  this.subscribers = [];
15
16
  this.keySubscribers = new Map();
16
17
  this.deepSubscribers = [];
17
18
  this.observer = (event, transaction) => { };
19
+ this.syncedObserver = (synced) => { };
18
20
  }
19
21
  isRoot() {
20
22
  return false;
@@ -22,6 +24,9 @@ class RhineVarItem {
22
24
  root() {
23
25
  return this.parent.root();
24
26
  }
27
+ getConnector() {
28
+ return this.root().connector;
29
+ }
25
30
  afterSynced(callback) {
26
31
  var _a;
27
32
  const connector = (_a = this.root()) === null || _a === void 0 ? void 0 : _a.connector;
@@ -77,15 +82,28 @@ class RhineVarItem {
77
82
  }
78
83
  return {};
79
84
  }
80
- toString() {
81
- return String(this.json());
85
+ string(indent = 2) {
86
+ return JSON.stringify(this.json(), null, indent);
87
+ }
88
+ subscribeSynced(callback) {
89
+ this.syncedSubscribers.push(callback);
90
+ return () => this.unsubscribeSynced(callback);
91
+ }
92
+ unsubscribeSynced(callback) {
93
+ this.syncedSubscribers = this.syncedSubscribers.filter(subscriber => subscriber !== callback);
94
+ }
95
+ unsubscribeAllSynced() {
96
+ this.syncedSubscribers = [];
97
+ }
98
+ emitSynced(synced) {
99
+ this.syncedSubscribers.forEach(subscriber => subscriber(synced));
82
100
  }
83
101
  subscribe(callback) {
84
102
  this.subscribers.push(callback);
85
103
  return () => this.unsubscribe(callback);
86
104
  }
87
105
  unsubscribe(callback) {
88
- this.subscribers = this.subscribers.filter(listener => listener !== callback);
106
+ this.subscribers = this.subscribers.filter(subscriber => subscriber !== callback);
89
107
  }
90
108
  unsubscribeAll() {
91
109
  this.subscribers = [];
@@ -98,8 +116,8 @@ class RhineVarItem {
98
116
  return () => this.unsubscribeKey(callback);
99
117
  }
100
118
  unsubscribeKey(callback) {
101
- this.keySubscribers.forEach((listeners, key) => {
102
- this.keySubscribers.set(key, listeners.filter(listener => listener !== callback));
119
+ this.keySubscribers.forEach((subscribers, key) => {
120
+ this.keySubscribers.set(key, subscribers.filter(subscriber => subscriber !== callback));
103
121
  });
104
122
  }
105
123
  unsubscribeAllKey() {
@@ -108,7 +126,7 @@ class RhineVarItem {
108
126
  emit(key, value, oldValue, type, nativeEvent, nativeTransaction) {
109
127
  this.subscribers.forEach(subscriber => subscriber(key, value, oldValue, type, nativeEvent, nativeTransaction));
110
128
  if (this.keySubscribers.has(key)) {
111
- this.keySubscribers.get(key).forEach(listener => listener(key, value, oldValue, type, nativeEvent, nativeTransaction));
129
+ this.keySubscribers.get(key).forEach(subscriber => subscriber(key, value, oldValue, type, nativeEvent, nativeTransaction));
112
130
  }
113
131
  }
114
132
  subscribeDeep(callback) {
@@ -116,7 +134,7 @@ class RhineVarItem {
116
134
  return () => this.unsubscribeDeep(callback);
117
135
  }
118
136
  unsubscribeDeep(callback) {
119
- this.deepSubscribers = this.deepSubscribers.filter(listener => listener !== callback);
137
+ this.deepSubscribers = this.deepSubscribers.filter(subscriber => subscriber !== callback);
120
138
  }
121
139
  unsubscribeAllDeep() {
122
140
  this.deepSubscribers = [];
@@ -140,6 +158,11 @@ class RhineVarItem {
140
158
  }
141
159
  // 开始观察当前Native的内容变化
142
160
  observe() {
161
+ var _a;
162
+ this.syncedObserver = (synced) => {
163
+ this.emitSynced(synced);
164
+ };
165
+ (_a = this.getConnector()) === null || _a === void 0 ? void 0 : _a.subscribeSynced(this.syncedObserver);
143
166
  const target = this.native;
144
167
  if (target instanceof yjs_1.Map) {
145
168
  this.observer = (event, transaction) => {
@@ -222,9 +245,13 @@ class RhineVarItem {
222
245
  }
223
246
  }
224
247
  unobserve() {
248
+ var _a;
225
249
  if (this.observer) {
226
250
  this.native.unobserve(this.observer);
227
251
  }
252
+ if (this.syncedObserver) {
253
+ (_a = this.getConnector()) === null || _a === void 0 ? void 0 : _a.unsubscribeSynced(this.syncedObserver);
254
+ }
228
255
  }
229
256
  }
230
257
  exports.default = RhineVarItem;
@@ -233,12 +260,17 @@ exports.RHINE_VAR_PREDEFINED_PROPERTIES = new Set([
233
260
  'native',
234
261
  'connector',
235
262
  'json',
236
- 'toString',
263
+ 'string',
237
264
  'parent',
238
265
  'isRoot',
239
266
  'root',
267
+ 'getConnector',
240
268
  'afterSynced',
241
269
  'waitSynced',
270
+ 'syncedSubscribers',
271
+ 'subscribeSynced',
272
+ 'unsubscribeSynced',
273
+ 'unsubscribeAllSynced',
242
274
  'subscribers',
243
275
  'subscribe',
244
276
  'unsubscribe',
@@ -251,6 +283,7 @@ exports.RHINE_VAR_PREDEFINED_PROPERTIES = new Set([
251
283
  'subscribeDeep',
252
284
  'unsubscribeDeep',
253
285
  'unsubscribeAllDeep',
286
+ 'emitSynced',
254
287
  'emit',
255
288
  'emitDeep',
256
289
  'observer',
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { rhineProxy, rhineProxyItem } from "./core/proxy/Proxy";
2
2
  import RhineVarItem from "./core/proxy/RhineVarItem";
3
3
  import { StoredRhineVarItem, ProxiedRhineVarItem, RecursiveCrossRhineVarItem, StoredRhineVar, ProxiedRhineVar, RecursiveCrossRhineVar } from "./core/proxy/ProxiedRhineVar";
4
- import WebsocketRhineConnector from "./core/connector/WebsocketRhineConnector";
4
+ import WebsocketConnector from "./core/connector/WebsocketConnector";
5
5
  import useRhine from "./react/hooks/useRhine";
6
6
  import useSynced from "./react/hooks/useSynced";
7
7
  import { Native, YPath } from "./core/native/Native";
8
- export { WebsocketRhineConnector, rhineProxy, rhineProxyItem, RhineVarItem, StoredRhineVarItem, ProxiedRhineVarItem, RecursiveCrossRhineVarItem, StoredRhineVar, ProxiedRhineVar, RecursiveCrossRhineVar, YPath, Native, useRhine, useSynced, };
8
+ export { WebsocketConnector, rhineProxy, rhineProxyItem, RhineVarItem, StoredRhineVarItem, ProxiedRhineVarItem, RecursiveCrossRhineVarItem, StoredRhineVar, ProxiedRhineVar, RecursiveCrossRhineVar, YPath, Native, useRhine, useSynced, };
9
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,cAAc,EAAC,2BAA2B;AAC9D,OAAO,YAAY,kCAAkC;AACrD,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,0BAA0B,EAC1B,cAAc,EACd,eAAe,EACf,sBAAsB,EACvB,qCAAqC;AACtC,OAAO,uBAAuB,iDAAiD;AAC/E,OAAO,QAAQ,+BAA8B;AAC7C,OAAO,SAAS,gCAA+B;AAC/C,OAAO,EAAC,MAAM,EAAE,KAAK,EAAC,6BAA6B;AAEnD,OAAO,EACL,uBAAuB,EACvB,UAAU,EACV,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,0BAA0B,EAC1B,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,KAAK,EACL,MAAM,EACN,QAAQ,EACR,SAAS,GACV,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,cAAc,EAAC,2BAA2B;AAC9D,OAAO,YAAY,kCAAkC;AACrD,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,0BAA0B,EAC1B,cAAc,EACd,eAAe,EACf,sBAAsB,EACvB,qCAAqC;AACtC,OAAO,kBAAkB,4CAA4C;AACrE,OAAO,QAAQ,+BAA8B;AAC7C,OAAO,SAAS,gCAA+B;AAC/C,OAAO,EAAC,MAAM,EAAE,KAAK,EAAC,6BAA6B;AAEnD,OAAO,EACL,kBAAkB,EAClB,UAAU,EACV,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,0BAA0B,EAC1B,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,KAAK,EACL,MAAM,EACN,QAAQ,EACR,SAAS,GACV,CAAA"}
package/dist/index.js CHANGED
@@ -3,14 +3,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.useSynced = exports.useRhine = exports.RhineVarItem = exports.rhineProxyItem = exports.rhineProxy = exports.WebsocketRhineConnector = void 0;
6
+ exports.useSynced = exports.useRhine = exports.RhineVarItem = exports.rhineProxyItem = exports.rhineProxy = exports.WebsocketConnector = void 0;
7
7
  const Proxy_1 = require("./core/proxy/Proxy");
8
8
  Object.defineProperty(exports, "rhineProxy", { enumerable: true, get: function () { return Proxy_1.rhineProxy; } });
9
9
  Object.defineProperty(exports, "rhineProxyItem", { enumerable: true, get: function () { return Proxy_1.rhineProxyItem; } });
10
10
  const RhineVarItem_1 = __importDefault(require("./core/proxy/RhineVarItem"));
11
11
  exports.RhineVarItem = RhineVarItem_1.default;
12
- const WebsocketRhineConnector_1 = __importDefault(require("./core/connector/WebsocketRhineConnector"));
13
- exports.WebsocketRhineConnector = WebsocketRhineConnector_1.default;
12
+ const WebsocketConnector_1 = __importDefault(require("./core/connector/WebsocketConnector"));
13
+ exports.WebsocketConnector = WebsocketConnector_1.default;
14
14
  const useRhine_1 = __importDefault(require("./react/hooks/useRhine"));
15
15
  exports.useRhine = useRhine_1.default;
16
16
  const useSynced_1 = __importDefault(require("./react/hooks/useSynced"));
@@ -1,3 +1,3 @@
1
1
  import { ProxiedRhineVar } from "../../core/proxy/ProxiedRhineVar";
2
- export default function useRhine<T extends object>(proxy: ProxiedRhineVar<T>): T;
2
+ export default function useRhine<T extends object>(proxy: ProxiedRhineVar<T>): Readonly<T>;
3
3
  //# sourceMappingURL=useRhine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useRhine.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/useRhine.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,eAAe,EAAC,yCAAqC;AAE7D,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,KAgB3E"}
1
+ {"version":3,"file":"useRhine.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/useRhine.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,eAAe,EAAC,yCAAqC;AAE7D,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAgBzF"}
@@ -4,17 +4,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.default = useRhine;
5
5
  const react_1 = require("react");
6
6
  function useRhine(proxy) {
7
- const getState = () => proxy.json();
8
- const [state, setState] = (0, react_1.useState)(getState);
7
+ const createSnapshot = () => proxy.json();
8
+ const [state, setState] = (0, react_1.useState)(createSnapshot);
9
9
  (0, react_1.useEffect)(() => {
10
- var _a;
11
- proxy.subscribeDeep(() => {
12
- // TODO: 提高性能
13
- setState(getState);
14
- });
15
- (_a = proxy.connector) === null || _a === void 0 ? void 0 : _a.addSyncedListener(() => {
16
- setState(getState);
17
- });
18
- }, []);
10
+ const updateState = () => setState(createSnapshot);
11
+ const unsubscribeSynced = proxy.subscribeSynced(updateState);
12
+ const unsubscribeDeep = proxy.subscribeDeep(updateState);
13
+ return () => {
14
+ unsubscribeSynced();
15
+ unsubscribeDeep();
16
+ };
17
+ }, [proxy]);
19
18
  return state;
20
19
  }
@@ -1,4 +1,4 @@
1
- import WebsocketRhineConnector from "../../core/connector/WebsocketRhineConnector";
1
+ import WebsocketConnector from "../../core/connector/WebsocketConnector";
2
2
  import { ProxiedRhineVar } from "../../core/proxy/ProxiedRhineVar";
3
- export default function useSynced(target?: WebsocketRhineConnector | ProxiedRhineVar<any>): boolean | undefined;
3
+ export default function useSynced(target?: WebsocketConnector | ProxiedRhineVar<any>): boolean;
4
4
  //# sourceMappingURL=useSynced.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useSynced.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/useSynced.ts"],"names":[],"mappings":"AAAA,OAAO,uBAAuB,qDAAiD;AAE/E,OAAO,EAAC,eAAe,EAAC,yCAAqC;AAE7D,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,MAAM,CAAC,EAAE,uBAAuB,GAAG,eAAe,CAAC,GAAG,CAAC,uBA0BxF"}
1
+ {"version":3,"file":"useSynced.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/useSynced.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,gDAA4C;AAErE,OAAO,EAAC,eAAe,EAAC,yCAAqC;AAG7D,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,MAAM,CAAC,EAAE,kBAAkB,GAAG,eAAe,CAAC,GAAG,CAAC,WAwBnF"}
@@ -4,30 +4,29 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.default = useSynced;
7
- const WebsocketRhineConnector_1 = __importDefault(require("../../core/connector/WebsocketRhineConnector"));
7
+ const WebsocketConnector_1 = __importDefault(require("../../core/connector/WebsocketConnector"));
8
8
  const react_1 = require("react");
9
+ const RhineVarItem_1 = __importDefault(require("../../core/proxy/RhineVarItem"));
9
10
  function useSynced(target) {
10
- let connector = null;
11
- if (target) {
12
- if (target instanceof WebsocketRhineConnector_1.default) {
11
+ const checkSynced = () => {
12
+ var _a;
13
+ let connector = null;
14
+ if (target instanceof WebsocketConnector_1.default) {
13
15
  connector = target;
14
16
  }
15
- else {
16
- connector = target.connector;
17
+ else if (target instanceof RhineVarItem_1.default) {
18
+ connector = target.getConnector();
17
19
  }
18
- }
19
- const [synced, setSynced] = (0, react_1.useState)(connector === null || connector === void 0 ? void 0 : connector.synced);
20
+ return (_a = connector === null || connector === void 0 ? void 0 : connector.synced) !== null && _a !== void 0 ? _a : false;
21
+ };
22
+ const [synced, setSynced] = (0, react_1.useState)(checkSynced);
20
23
  (0, react_1.useEffect)(() => {
21
- let listener = null;
22
- if (connector) {
23
- listener = (synced) => setSynced(synced);
24
- connector.addSyncedListener(listener);
24
+ if (target instanceof WebsocketConnector_1.default) {
25
+ return target.subscribeSynced((value) => setSynced(value));
25
26
  }
26
- return () => {
27
- if (listener && connector) {
28
- connector.removeSyncedListener(listener);
29
- }
30
- };
31
- }, []);
27
+ if (target instanceof RhineVarItem_1.default) {
28
+ return target.subscribeSynced((value) => setSynced(value));
29
+ }
30
+ }, [target]);
32
31
  return synced;
33
32
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rhine-var",
3
- "version": "0.4.10",
3
+ "version": "0.5.0",
4
4
  "description": "Variables that support multi-user collaboration and persistence, making collaboration and variable operations as simple as possible, with strict and well-defined type hints.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",