@yorkie-js/sdk 0.6.49 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,277 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <title>Tree Schema Example</title>
6
+ <link rel="stylesheet" href="style.css" />
7
+ <style>
8
+ .tree-schema {
9
+ margin: 1rem;
10
+ font-family: monospace;
11
+ }
12
+ .tree-schema button {
13
+ margin: 4px;
14
+ padding: 6px 12px;
15
+ border: 1px solid #ccc;
16
+ border-radius: 4px;
17
+ background: #f5f5f5;
18
+ }
19
+ .tree-schema button:hover {
20
+ background: #e0e0e0;
21
+ }
22
+ .tree-schema button.valid {
23
+ border-color: #4caf50;
24
+ }
25
+ .tree-schema button.invalid {
26
+ border-color: #f44336;
27
+ }
28
+ .error-holder {
29
+ color: red;
30
+ margin: 10px 1rem;
31
+ font-family: monospace;
32
+ white-space: pre-wrap;
33
+ }
34
+ .schema-info {
35
+ margin: 1rem;
36
+ padding: 12px;
37
+ background: #f0f0f0;
38
+ border-radius: 4px;
39
+ font-family: monospace;
40
+ font-size: 0.85rem;
41
+ white-space: pre;
42
+ }
43
+ #tree-xml {
44
+ margin: 1rem;
45
+ padding: 12px;
46
+ background: #f8f8f8;
47
+ border: 1px solid #ddd;
48
+ border-radius: 4px;
49
+ font-family: monospace;
50
+ font-size: 0.85rem;
51
+ white-space: pre-wrap;
52
+ }
53
+ </style>
54
+ </head>
55
+ <body>
56
+ <div>
57
+ <div id="network-status"></div>
58
+ <div id="online-clients"></div>
59
+
60
+ <div class="schema-info">Schema: yorkie.Tree&lt;{
61
+ doc: { content: "block+"; }
62
+ paragraph: { content: "text*"; marks: "bold italic"; group: "block"; }
63
+ heading: { content: "text*"; marks: "bold"; group: "block"; }
64
+ text: {}
65
+ }&gt;</div>
66
+
67
+ <div class="tree-schema">
68
+ Valid operations:
69
+ <button class="valid" id="btn-add-paragraph">Add paragraph</button>
70
+ <button class="valid" id="btn-add-heading">Add heading</button>
71
+ <button class="valid" id="btn-edit-text">Edit first text</button>
72
+ <button id="btn-reset">Reset tree</button>
73
+ </div>
74
+ <div class="tree-schema">
75
+ Invalid operations (schema violation):
76
+ <button class="invalid" id="btn-add-unknown">Add &lt;div&gt; node</button>
77
+ <button class="invalid" id="btn-text-under-doc">Add text under doc</button>
78
+ </div>
79
+
80
+ <div class="error-holder" id="error-holder"></div>
81
+ <div id="tree-xml"></div>
82
+ <pre style="white-space: pre-wrap" id="log-holder"></pre>
83
+ </div>
84
+ <script type="module">
85
+ import './src/yorkie.ts';
86
+ import Network from './devtool/network.js';
87
+
88
+ const statusHolder = document.getElementById('network-status');
89
+ const onlineClientsHolder = document.getElementById('online-clients');
90
+ const logHolder = document.getElementById('log-holder');
91
+ const errorHolder = document.getElementById('error-holder');
92
+ const treeXmlHolder = document.getElementById('tree-xml');
93
+
94
+ function displayOnlineClients(presences, myClientID) {
95
+ const usernames = [];
96
+ for (const { clientID, presence } of presences) {
97
+ usernames.push(
98
+ clientID === myClientID ? `<b>${clientID}</b>` : clientID,
99
+ );
100
+ }
101
+ onlineClientsHolder.innerHTML = JSON.stringify(usernames);
102
+ }
103
+
104
+ function updateTreeDisplay(doc) {
105
+ try {
106
+ const tree = doc.getRoot().content;
107
+ if (tree) {
108
+ treeXmlHolder.textContent = 'Tree XML: ' + tree.toXML();
109
+ }
110
+ } catch (e) {
111
+ // tree may not be ready
112
+ }
113
+ logHolder.innerHTML = JSON.stringify(doc.getRoot().toJS(), null, 2);
114
+ }
115
+
116
+ async function main() {
117
+ try {
118
+ const client = new yorkie.Client({
119
+ rpcAddr: 'http://localhost:8080',
120
+ });
121
+ await client.activate();
122
+
123
+ const doc = new yorkie.Document('tree-schema', {
124
+ enableDevtools: true,
125
+ });
126
+ doc.subscribe('connection', new Network(statusHolder).statusListener);
127
+ doc.subscribe('presence', (event) => {
128
+ if (event.type === 'presence-changed') return;
129
+ displayOnlineClients(doc.getPresences(), client.getID());
130
+ });
131
+ doc.subscribe((event) => {
132
+ updateTreeDisplay(doc);
133
+ });
134
+
135
+ // Attach with tree schema.
136
+ // NOTE: The schema 'tree-test@1' must be created on the server
137
+ // beforehand with the matching TreeNodeRules.
138
+ await client.attach(doc, {
139
+ schema: 'tree-test@1',
140
+ });
141
+
142
+ // Initialize tree with valid structure: doc > paragraph > text
143
+ doc.update((root) => {
144
+ if (!root.content) {
145
+ root.content = new yorkie.Tree({
146
+ type: 'doc',
147
+ children: [
148
+ {
149
+ type: 'paragraph',
150
+ children: [{ type: 'text', value: 'Hello, Tree Schema!' }],
151
+ },
152
+ ],
153
+ });
154
+ }
155
+ }, 'initialize tree');
156
+
157
+ updateTreeDisplay(doc);
158
+
159
+ // ── Valid operations ──
160
+
161
+ document
162
+ .getElementById('btn-add-paragraph')
163
+ .addEventListener('click', () => {
164
+ try {
165
+ errorHolder.textContent = '';
166
+ doc.update((root) => {
167
+ const tree = root.content;
168
+ const size = tree.getSize();
169
+ tree.edit(size, size, {
170
+ type: 'paragraph',
171
+ children: [{ type: 'text', value: 'New paragraph' }],
172
+ });
173
+ });
174
+ } catch (e) {
175
+ errorHolder.textContent = e.message;
176
+ }
177
+ });
178
+
179
+ document
180
+ .getElementById('btn-add-heading')
181
+ .addEventListener('click', () => {
182
+ try {
183
+ errorHolder.textContent = '';
184
+ doc.update((root) => {
185
+ const tree = root.content;
186
+ tree.edit(0, 0, {
187
+ type: 'heading',
188
+ children: [{ type: 'text', value: 'New heading' }],
189
+ });
190
+ });
191
+ } catch (e) {
192
+ errorHolder.textContent = e.message;
193
+ }
194
+ });
195
+
196
+ document
197
+ .getElementById('btn-edit-text')
198
+ .addEventListener('click', () => {
199
+ try {
200
+ errorHolder.textContent = '';
201
+ doc.update((root) => {
202
+ const tree = root.content;
203
+ tree.edit(2, 2, { type: 'text', value: ' [edited]' });
204
+ });
205
+ } catch (e) {
206
+ errorHolder.textContent = e.message;
207
+ }
208
+ });
209
+
210
+ document
211
+ .getElementById('btn-reset')
212
+ .addEventListener('click', () => {
213
+ try {
214
+ errorHolder.textContent = '';
215
+ doc.update((root) => {
216
+ root.content = new yorkie.Tree({
217
+ type: 'doc',
218
+ children: [
219
+ {
220
+ type: 'paragraph',
221
+ children: [
222
+ { type: 'text', value: 'Hello, Tree Schema!' },
223
+ ],
224
+ },
225
+ ],
226
+ });
227
+ }, 'reset tree');
228
+ } catch (e) {
229
+ errorHolder.textContent = e.message;
230
+ }
231
+ });
232
+
233
+ // ── Invalid operations (schema violation) ──
234
+
235
+ document
236
+ .getElementById('btn-add-unknown')
237
+ .addEventListener('click', () => {
238
+ try {
239
+ errorHolder.textContent = '';
240
+ doc.update((root) => {
241
+ const tree = root.content;
242
+ tree.edit(0, 0, {
243
+ type: 'div',
244
+ children: [{ type: 'text', value: 'unknown node' }],
245
+ });
246
+ });
247
+ } catch (e) {
248
+ errorHolder.textContent = e.message;
249
+ }
250
+ });
251
+
252
+ document
253
+ .getElementById('btn-text-under-doc')
254
+ .addEventListener('click', () => {
255
+ try {
256
+ errorHolder.textContent = '';
257
+ doc.update((root) => {
258
+ const tree = root.content;
259
+ tree.edit(0, 0, {
260
+ type: 'text',
261
+ value: 'text directly under doc',
262
+ });
263
+ });
264
+ } catch (e) {
265
+ errorHolder.textContent = e.message;
266
+ }
267
+ });
268
+ } catch (e) {
269
+ console.error(e);
270
+ errorHolder.textContent = e.message;
271
+ }
272
+ }
273
+
274
+ main();
275
+ </script>
276
+ </body>
277
+ </html>
@@ -1920,12 +1920,12 @@ declare class CRDTTree extends CRDTElement implements GCParent {
1920
1920
  * `edit` edits the tree with the given range and content.
1921
1921
  * If the content is undefined, the range will be removed.
1922
1922
  */
1923
- edit(range: [CRDTTreePos, CRDTTreePos], contents: Array<CRDTTreeNode> | undefined, splitLevel: number, editedAt: TimeTicket, issueTimeTicket: (() => TimeTicket) | undefined, versionVector?: VersionVector): [Array<TreeChange>, Array<GCPair>, DataSize];
1923
+ edit(range: [CRDTTreePos, CRDTTreePos], contents: Array<CRDTTreeNode> | undefined, splitLevel: number, editedAt: TimeTicket, issueTimeTicket: (() => TimeTicket) | undefined, versionVector?: VersionVector): [Array<TreeChange>, Array<GCPair>, DataSize, Array<CRDTTreeNode>, number];
1924
1924
  /**
1925
1925
  * `editT` edits the given range with the given value.
1926
1926
  * This method uses indexes instead of a pair of TreePos for testing.
1927
1927
  */
1928
- editT(range: [number, number], contents: Array<CRDTTreeNode> | undefined, splitLevel: number, editedAt: TimeTicket, issueTimeTicket: () => TimeTicket): [Array<TreeChange>, Array<GCPair>, DataSize];
1928
+ editT(range: [number, number], contents: Array<CRDTTreeNode> | undefined, splitLevel: number, editedAt: TimeTicket, issueTimeTicket: () => TimeTicket): [Array<TreeChange>, Array<GCPair>, DataSize, Array<CRDTTreeNode>, number];
1929
1929
  /**
1930
1930
  * `move` move the given source range to the given target range.
1931
1931
  */
@@ -5450,6 +5450,10 @@ declare type Rule_2 = Message<"yorkie.v1.Rule"> & {
5450
5450
  * @generated from field: string type = 2;
5451
5451
  */
5452
5452
  type: string;
5453
+ /**
5454
+ * @generated from field: repeated yorkie.v1.TreeNodeRule tree_nodes = 3;
5455
+ */
5456
+ treeNodes: TreeNodeRule[];
5453
5457
  };
5454
5458
 
5455
5459
  /**
@@ -6477,6 +6481,28 @@ declare type TreeNodeInfo = {
6477
6481
  */
6478
6482
  declare type TreeNodePair = [CRDTTreeNode, CRDTTreeNode];
6479
6483
 
6484
+ /**
6485
+ * @generated from message yorkie.v1.TreeNodeRule
6486
+ */
6487
+ declare type TreeNodeRule = Message<"yorkie.v1.TreeNodeRule"> & {
6488
+ /**
6489
+ * @generated from field: string node_type = 1;
6490
+ */
6491
+ nodeType: string;
6492
+ /**
6493
+ * @generated from field: string content = 2;
6494
+ */
6495
+ content: string;
6496
+ /**
6497
+ * @generated from field: string marks = 3;
6498
+ */
6499
+ marks: string;
6500
+ /**
6501
+ * @generated from field: string group = 4;
6502
+ */
6503
+ group: string;
6504
+ };
6505
+
6480
6506
  /**
6481
6507
  * @generated from message yorkie.v1.TreeNodes
6482
6508
  */