@coaction/yjs 1.4.0 → 1.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/dist/index.js +138 -123
- package/dist/index.mjs +139 -124
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -44,9 +44,12 @@ __export(src_exports, {
|
|
|
44
44
|
bindYjs: () => bindYjs,
|
|
45
45
|
yjs: () => yjs
|
|
46
46
|
});
|
|
47
|
-
var
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
var Y4 = __toESM(require("yjs"));
|
|
48
|
+
|
|
49
|
+
// src/remoteOperations.ts
|
|
50
|
+
var Y2 = __toESM(require("yjs"));
|
|
51
|
+
|
|
52
|
+
// src/shared.ts
|
|
50
53
|
var scheduleMicrotask = (callback) => {
|
|
51
54
|
if (typeof queueMicrotask === "function") {
|
|
52
55
|
queueMicrotask(callback);
|
|
@@ -67,6 +70,9 @@ function isPlainObject(value) {
|
|
|
67
70
|
const prototype = Object.getPrototypeOf(value);
|
|
68
71
|
return prototype === Object.prototype || prototype === null;
|
|
69
72
|
}
|
|
73
|
+
|
|
74
|
+
// src/yjsValue.ts
|
|
75
|
+
var Y = __toESM(require("yjs"));
|
|
70
76
|
function toPlainObject(value) {
|
|
71
77
|
const next = {};
|
|
72
78
|
value.forEach((item, key) => {
|
|
@@ -115,6 +121,125 @@ function toYValue(value) {
|
|
|
115
121
|
}
|
|
116
122
|
return value;
|
|
117
123
|
}
|
|
124
|
+
|
|
125
|
+
// src/remoteOperations.ts
|
|
126
|
+
function isSetStateReentryError(error) {
|
|
127
|
+
return error instanceof Error && error.message === "setState cannot be called within the updater";
|
|
128
|
+
}
|
|
129
|
+
function cloneForStore(value) {
|
|
130
|
+
if (typeof value === "object" && value !== null) {
|
|
131
|
+
return clone(value);
|
|
132
|
+
}
|
|
133
|
+
return value;
|
|
134
|
+
}
|
|
135
|
+
function toPathKey(path) {
|
|
136
|
+
return path.map((segment) => `${typeof segment}:${String(segment)}`).join("|");
|
|
137
|
+
}
|
|
138
|
+
function compactOperations(operations) {
|
|
139
|
+
const deduplicated = /* @__PURE__ */ new Map();
|
|
140
|
+
for (const operation of operations) {
|
|
141
|
+
const key = toPathKey(operation.path);
|
|
142
|
+
if (deduplicated.has(key)) {
|
|
143
|
+
deduplicated.delete(key);
|
|
144
|
+
}
|
|
145
|
+
deduplicated.set(key, operation);
|
|
146
|
+
}
|
|
147
|
+
return Array.from(deduplicated.values()).sort(
|
|
148
|
+
(left, right) => left.path.length - right.path.length
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
function getYValueAtPath(root, path) {
|
|
152
|
+
let current = root;
|
|
153
|
+
for (const segment of path) {
|
|
154
|
+
if (current instanceof Y2.Map) {
|
|
155
|
+
current = current.get(String(segment));
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
if (current instanceof Y2.Array) {
|
|
159
|
+
const index = typeof segment === "number" ? segment : Number.parseInt(segment, 10);
|
|
160
|
+
if (!Number.isInteger(index)) {
|
|
161
|
+
return void 0;
|
|
162
|
+
}
|
|
163
|
+
current = current.get(index);
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
return void 0;
|
|
167
|
+
}
|
|
168
|
+
return current;
|
|
169
|
+
}
|
|
170
|
+
function setAtPath(target, path, value) {
|
|
171
|
+
if (path.length === 0) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
let current = target;
|
|
175
|
+
for (let index = 0; index < path.length - 1; index += 1) {
|
|
176
|
+
const segment = path[index];
|
|
177
|
+
const nextSegment = path[index + 1];
|
|
178
|
+
const nextValue = current[segment];
|
|
179
|
+
if (typeof nextValue !== "object" || nextValue === null) {
|
|
180
|
+
current[segment] = typeof nextSegment === "number" ? [] : {};
|
|
181
|
+
}
|
|
182
|
+
current = current[segment];
|
|
183
|
+
}
|
|
184
|
+
const leaf = path[path.length - 1];
|
|
185
|
+
current[leaf] = cloneForStore(value);
|
|
186
|
+
}
|
|
187
|
+
function deleteAtPath(target, path) {
|
|
188
|
+
if (path.length === 0) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
let current = target;
|
|
192
|
+
for (let index = 0; index < path.length - 1; index += 1) {
|
|
193
|
+
current = current[path[index]];
|
|
194
|
+
if (typeof current !== "object" || current === null) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
const leaf = path[path.length - 1];
|
|
199
|
+
if (Array.isArray(current) && typeof leaf === "number") {
|
|
200
|
+
if (leaf >= 0 && leaf < current.length) {
|
|
201
|
+
current.splice(leaf, 1);
|
|
202
|
+
}
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
delete current[leaf];
|
|
206
|
+
}
|
|
207
|
+
function collectRemoteOperations(events, stateMap) {
|
|
208
|
+
const operations = [];
|
|
209
|
+
for (const event of events) {
|
|
210
|
+
if (event instanceof Y2.YMapEvent) {
|
|
211
|
+
for (const changedKey of event.keysChanged) {
|
|
212
|
+
const path = [...event.path, changedKey];
|
|
213
|
+
const keyChange = event.changes.keys.get(changedKey);
|
|
214
|
+
if (keyChange?.action === "delete") {
|
|
215
|
+
operations.push({
|
|
216
|
+
type: "delete",
|
|
217
|
+
path
|
|
218
|
+
});
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
operations.push({
|
|
222
|
+
type: "set",
|
|
223
|
+
path,
|
|
224
|
+
value: toPlainValue(getYValueAtPath(stateMap, path))
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
if (event instanceof Y2.YArrayEvent) {
|
|
230
|
+
const path = [...event.path];
|
|
231
|
+
operations.push({
|
|
232
|
+
type: "set",
|
|
233
|
+
path,
|
|
234
|
+
value: toPlainValue(getYValueAtPath(stateMap, path))
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return operations;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// src/sync.ts
|
|
242
|
+
var Y3 = __toESM(require("yjs"));
|
|
118
243
|
function isEqualValue(left, right) {
|
|
119
244
|
if (Object.is(left, right)) {
|
|
120
245
|
return true;
|
|
@@ -164,7 +289,7 @@ function syncObjectToYMap(target, previous, source) {
|
|
|
164
289
|
}
|
|
165
290
|
const current = target.get(key);
|
|
166
291
|
if (Array.isArray(nextValue)) {
|
|
167
|
-
if (Array.isArray(previousValue) && current instanceof
|
|
292
|
+
if (Array.isArray(previousValue) && current instanceof Y3.Array) {
|
|
168
293
|
syncArrayToYArray(current, previousValue, nextValue);
|
|
169
294
|
} else {
|
|
170
295
|
target.set(key, createYArray(nextValue));
|
|
@@ -172,7 +297,7 @@ function syncObjectToYMap(target, previous, source) {
|
|
|
172
297
|
continue;
|
|
173
298
|
}
|
|
174
299
|
if (isPlainObject(nextValue)) {
|
|
175
|
-
if (isPlainObject(previousValue) && current instanceof
|
|
300
|
+
if (isPlainObject(previousValue) && current instanceof Y3.Map) {
|
|
176
301
|
syncObjectToYMap(current, previousValue, nextValue);
|
|
177
302
|
} else {
|
|
178
303
|
target.set(key, createYMap(nextValue));
|
|
@@ -207,7 +332,7 @@ function syncArrayToYArray(target, previous, source) {
|
|
|
207
332
|
}
|
|
208
333
|
const current = target.get(index);
|
|
209
334
|
if (Array.isArray(nextValue)) {
|
|
210
|
-
if (Array.isArray(previousValue) && current instanceof
|
|
335
|
+
if (Array.isArray(previousValue) && current instanceof Y3.Array) {
|
|
211
336
|
syncArrayToYArray(current, previousValue, nextValue);
|
|
212
337
|
} else {
|
|
213
338
|
target.delete(index, 1);
|
|
@@ -216,7 +341,7 @@ function syncArrayToYArray(target, previous, source) {
|
|
|
216
341
|
continue;
|
|
217
342
|
}
|
|
218
343
|
if (isPlainObject(nextValue)) {
|
|
219
|
-
if (isPlainObject(previousValue) && current instanceof
|
|
344
|
+
if (isPlainObject(previousValue) && current instanceof Y3.Map) {
|
|
220
345
|
syncObjectToYMap(current, previousValue, nextValue);
|
|
221
346
|
} else {
|
|
222
347
|
target.delete(index, 1);
|
|
@@ -231,120 +356,10 @@ function syncArrayToYArray(target, previous, source) {
|
|
|
231
356
|
}
|
|
232
357
|
}
|
|
233
358
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
if (typeof value === "object" && value !== null) {
|
|
239
|
-
return clone(value);
|
|
240
|
-
}
|
|
241
|
-
return value;
|
|
242
|
-
}
|
|
243
|
-
function toPathKey(path) {
|
|
244
|
-
return path.map((segment) => `${typeof segment}:${String(segment)}`).join("|");
|
|
245
|
-
}
|
|
246
|
-
function compactOperations(operations) {
|
|
247
|
-
const deduplicated = /* @__PURE__ */ new Map();
|
|
248
|
-
for (const operation of operations) {
|
|
249
|
-
const key = toPathKey(operation.path);
|
|
250
|
-
if (deduplicated.has(key)) {
|
|
251
|
-
deduplicated.delete(key);
|
|
252
|
-
}
|
|
253
|
-
deduplicated.set(key, operation);
|
|
254
|
-
}
|
|
255
|
-
return Array.from(deduplicated.values()).sort(
|
|
256
|
-
(left, right) => left.path.length - right.path.length
|
|
257
|
-
);
|
|
258
|
-
}
|
|
259
|
-
function getYValueAtPath(root, path) {
|
|
260
|
-
let current = root;
|
|
261
|
-
for (const segment of path) {
|
|
262
|
-
if (current instanceof Y.Map) {
|
|
263
|
-
current = current.get(String(segment));
|
|
264
|
-
continue;
|
|
265
|
-
}
|
|
266
|
-
if (current instanceof Y.Array) {
|
|
267
|
-
const index = typeof segment === "number" ? segment : Number.parseInt(segment, 10);
|
|
268
|
-
if (!Number.isInteger(index)) {
|
|
269
|
-
return void 0;
|
|
270
|
-
}
|
|
271
|
-
current = current.get(index);
|
|
272
|
-
continue;
|
|
273
|
-
}
|
|
274
|
-
return void 0;
|
|
275
|
-
}
|
|
276
|
-
return current;
|
|
277
|
-
}
|
|
278
|
-
function setAtPath(target, path, value) {
|
|
279
|
-
if (path.length === 0) {
|
|
280
|
-
return;
|
|
281
|
-
}
|
|
282
|
-
let current = target;
|
|
283
|
-
for (let index = 0; index < path.length - 1; index += 1) {
|
|
284
|
-
const segment = path[index];
|
|
285
|
-
const nextSegment = path[index + 1];
|
|
286
|
-
const nextValue = current[segment];
|
|
287
|
-
if (typeof nextValue !== "object" || nextValue === null) {
|
|
288
|
-
current[segment] = typeof nextSegment === "number" ? [] : {};
|
|
289
|
-
}
|
|
290
|
-
current = current[segment];
|
|
291
|
-
}
|
|
292
|
-
const leaf = path[path.length - 1];
|
|
293
|
-
current[leaf] = cloneForStore(value);
|
|
294
|
-
}
|
|
295
|
-
function deleteAtPath(target, path) {
|
|
296
|
-
if (path.length === 0) {
|
|
297
|
-
return;
|
|
298
|
-
}
|
|
299
|
-
let current = target;
|
|
300
|
-
for (let index = 0; index < path.length - 1; index += 1) {
|
|
301
|
-
current = current[path[index]];
|
|
302
|
-
if (typeof current !== "object" || current === null) {
|
|
303
|
-
return;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
const leaf = path[path.length - 1];
|
|
307
|
-
if (Array.isArray(current) && typeof leaf === "number") {
|
|
308
|
-
if (leaf >= 0 && leaf < current.length) {
|
|
309
|
-
current.splice(leaf, 1);
|
|
310
|
-
}
|
|
311
|
-
return;
|
|
312
|
-
}
|
|
313
|
-
delete current[leaf];
|
|
314
|
-
}
|
|
315
|
-
function collectRemoteOperations(events, stateMap) {
|
|
316
|
-
const operations = [];
|
|
317
|
-
for (const event of events) {
|
|
318
|
-
if (event instanceof Y.YMapEvent) {
|
|
319
|
-
for (const changedKey of event.keysChanged) {
|
|
320
|
-
const path = [...event.path, changedKey];
|
|
321
|
-
const keyChange = event.changes.keys.get(changedKey);
|
|
322
|
-
if (keyChange?.action === "delete") {
|
|
323
|
-
operations.push({
|
|
324
|
-
type: "delete",
|
|
325
|
-
path
|
|
326
|
-
});
|
|
327
|
-
continue;
|
|
328
|
-
}
|
|
329
|
-
operations.push({
|
|
330
|
-
type: "set",
|
|
331
|
-
path,
|
|
332
|
-
value: toPlainValue(getYValueAtPath(stateMap, path))
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
|
-
continue;
|
|
336
|
-
}
|
|
337
|
-
if (event instanceof Y.YArrayEvent) {
|
|
338
|
-
const path = [...event.path];
|
|
339
|
-
operations.push({
|
|
340
|
-
type: "set",
|
|
341
|
-
path,
|
|
342
|
-
value: toPlainValue(getYValueAtPath(stateMap, path))
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
return operations;
|
|
347
|
-
}
|
|
359
|
+
|
|
360
|
+
// src/index.ts
|
|
361
|
+
__reExport(src_exports, require("yjs"));
|
|
362
|
+
var STATE_KEY = "state";
|
|
348
363
|
var __unsafeTestOnly__ = {
|
|
349
364
|
getYValueAtPath: (root, path) => getYValueAtPath(root, path),
|
|
350
365
|
setAtPath: (target, path, value) => {
|
|
@@ -358,7 +373,7 @@ var bindYjs = (store, options = {}) => {
|
|
|
358
373
|
if (store.share === "client") {
|
|
359
374
|
throw new Error("Yjs binding is not supported in client store mode.");
|
|
360
375
|
}
|
|
361
|
-
const doc = options.doc ?? new
|
|
376
|
+
const doc = options.doc ?? new Y4.Doc();
|
|
362
377
|
const key = options.key ?? `coaction:${store.name}`;
|
|
363
378
|
const map = doc.getMap(key);
|
|
364
379
|
const localOrigin = /* @__PURE__ */ Symbol(`coaction-yjs:${store.name}`);
|
|
@@ -406,7 +421,7 @@ var bindYjs = (store, options = {}) => {
|
|
|
406
421
|
};
|
|
407
422
|
const getStateMap = () => {
|
|
408
423
|
const state = map.get(STATE_KEY);
|
|
409
|
-
if (state instanceof
|
|
424
|
+
if (state instanceof Y4.Map) {
|
|
410
425
|
return state;
|
|
411
426
|
}
|
|
412
427
|
return null;
|
package/dist/index.mjs
CHANGED
|
@@ -31,10 +31,12 @@ __export(src_exports, {
|
|
|
31
31
|
bindYjs: () => bindYjs,
|
|
32
32
|
yjs: () => yjs
|
|
33
33
|
});
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
import * as Y4 from "yjs";
|
|
35
|
+
|
|
36
|
+
// src/remoteOperations.ts
|
|
37
|
+
import * as Y2 from "yjs";
|
|
38
|
+
|
|
39
|
+
// src/shared.ts
|
|
38
40
|
var scheduleMicrotask = (callback) => {
|
|
39
41
|
if (typeof queueMicrotask === "function") {
|
|
40
42
|
queueMicrotask(callback);
|
|
@@ -55,6 +57,9 @@ function isPlainObject(value) {
|
|
|
55
57
|
const prototype = Object.getPrototypeOf(value);
|
|
56
58
|
return prototype === Object.prototype || prototype === null;
|
|
57
59
|
}
|
|
60
|
+
|
|
61
|
+
// src/yjsValue.ts
|
|
62
|
+
import * as Y from "yjs";
|
|
58
63
|
function toPlainObject(value) {
|
|
59
64
|
const next = {};
|
|
60
65
|
value.forEach((item, key) => {
|
|
@@ -103,6 +108,125 @@ function toYValue(value) {
|
|
|
103
108
|
}
|
|
104
109
|
return value;
|
|
105
110
|
}
|
|
111
|
+
|
|
112
|
+
// src/remoteOperations.ts
|
|
113
|
+
function isSetStateReentryError(error) {
|
|
114
|
+
return error instanceof Error && error.message === "setState cannot be called within the updater";
|
|
115
|
+
}
|
|
116
|
+
function cloneForStore(value) {
|
|
117
|
+
if (typeof value === "object" && value !== null) {
|
|
118
|
+
return clone(value);
|
|
119
|
+
}
|
|
120
|
+
return value;
|
|
121
|
+
}
|
|
122
|
+
function toPathKey(path) {
|
|
123
|
+
return path.map((segment) => `${typeof segment}:${String(segment)}`).join("|");
|
|
124
|
+
}
|
|
125
|
+
function compactOperations(operations) {
|
|
126
|
+
const deduplicated = /* @__PURE__ */ new Map();
|
|
127
|
+
for (const operation of operations) {
|
|
128
|
+
const key = toPathKey(operation.path);
|
|
129
|
+
if (deduplicated.has(key)) {
|
|
130
|
+
deduplicated.delete(key);
|
|
131
|
+
}
|
|
132
|
+
deduplicated.set(key, operation);
|
|
133
|
+
}
|
|
134
|
+
return Array.from(deduplicated.values()).sort(
|
|
135
|
+
(left, right) => left.path.length - right.path.length
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
function getYValueAtPath(root, path) {
|
|
139
|
+
let current = root;
|
|
140
|
+
for (const segment of path) {
|
|
141
|
+
if (current instanceof Y2.Map) {
|
|
142
|
+
current = current.get(String(segment));
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (current instanceof Y2.Array) {
|
|
146
|
+
const index = typeof segment === "number" ? segment : Number.parseInt(segment, 10);
|
|
147
|
+
if (!Number.isInteger(index)) {
|
|
148
|
+
return void 0;
|
|
149
|
+
}
|
|
150
|
+
current = current.get(index);
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
return void 0;
|
|
154
|
+
}
|
|
155
|
+
return current;
|
|
156
|
+
}
|
|
157
|
+
function setAtPath(target, path, value) {
|
|
158
|
+
if (path.length === 0) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
let current = target;
|
|
162
|
+
for (let index = 0; index < path.length - 1; index += 1) {
|
|
163
|
+
const segment = path[index];
|
|
164
|
+
const nextSegment = path[index + 1];
|
|
165
|
+
const nextValue = current[segment];
|
|
166
|
+
if (typeof nextValue !== "object" || nextValue === null) {
|
|
167
|
+
current[segment] = typeof nextSegment === "number" ? [] : {};
|
|
168
|
+
}
|
|
169
|
+
current = current[segment];
|
|
170
|
+
}
|
|
171
|
+
const leaf = path[path.length - 1];
|
|
172
|
+
current[leaf] = cloneForStore(value);
|
|
173
|
+
}
|
|
174
|
+
function deleteAtPath(target, path) {
|
|
175
|
+
if (path.length === 0) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
let current = target;
|
|
179
|
+
for (let index = 0; index < path.length - 1; index += 1) {
|
|
180
|
+
current = current[path[index]];
|
|
181
|
+
if (typeof current !== "object" || current === null) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
const leaf = path[path.length - 1];
|
|
186
|
+
if (Array.isArray(current) && typeof leaf === "number") {
|
|
187
|
+
if (leaf >= 0 && leaf < current.length) {
|
|
188
|
+
current.splice(leaf, 1);
|
|
189
|
+
}
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
delete current[leaf];
|
|
193
|
+
}
|
|
194
|
+
function collectRemoteOperations(events, stateMap) {
|
|
195
|
+
const operations = [];
|
|
196
|
+
for (const event of events) {
|
|
197
|
+
if (event instanceof Y2.YMapEvent) {
|
|
198
|
+
for (const changedKey of event.keysChanged) {
|
|
199
|
+
const path = [...event.path, changedKey];
|
|
200
|
+
const keyChange = event.changes.keys.get(changedKey);
|
|
201
|
+
if (keyChange?.action === "delete") {
|
|
202
|
+
operations.push({
|
|
203
|
+
type: "delete",
|
|
204
|
+
path
|
|
205
|
+
});
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
operations.push({
|
|
209
|
+
type: "set",
|
|
210
|
+
path,
|
|
211
|
+
value: toPlainValue(getYValueAtPath(stateMap, path))
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
if (event instanceof Y2.YArrayEvent) {
|
|
217
|
+
const path = [...event.path];
|
|
218
|
+
operations.push({
|
|
219
|
+
type: "set",
|
|
220
|
+
path,
|
|
221
|
+
value: toPlainValue(getYValueAtPath(stateMap, path))
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return operations;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// src/sync.ts
|
|
229
|
+
import * as Y3 from "yjs";
|
|
106
230
|
function isEqualValue(left, right) {
|
|
107
231
|
if (Object.is(left, right)) {
|
|
108
232
|
return true;
|
|
@@ -152,7 +276,7 @@ function syncObjectToYMap(target, previous, source) {
|
|
|
152
276
|
}
|
|
153
277
|
const current = target.get(key);
|
|
154
278
|
if (Array.isArray(nextValue)) {
|
|
155
|
-
if (Array.isArray(previousValue) && current instanceof
|
|
279
|
+
if (Array.isArray(previousValue) && current instanceof Y3.Array) {
|
|
156
280
|
syncArrayToYArray(current, previousValue, nextValue);
|
|
157
281
|
} else {
|
|
158
282
|
target.set(key, createYArray(nextValue));
|
|
@@ -160,7 +284,7 @@ function syncObjectToYMap(target, previous, source) {
|
|
|
160
284
|
continue;
|
|
161
285
|
}
|
|
162
286
|
if (isPlainObject(nextValue)) {
|
|
163
|
-
if (isPlainObject(previousValue) && current instanceof
|
|
287
|
+
if (isPlainObject(previousValue) && current instanceof Y3.Map) {
|
|
164
288
|
syncObjectToYMap(current, previousValue, nextValue);
|
|
165
289
|
} else {
|
|
166
290
|
target.set(key, createYMap(nextValue));
|
|
@@ -195,7 +319,7 @@ function syncArrayToYArray(target, previous, source) {
|
|
|
195
319
|
}
|
|
196
320
|
const current = target.get(index);
|
|
197
321
|
if (Array.isArray(nextValue)) {
|
|
198
|
-
if (Array.isArray(previousValue) && current instanceof
|
|
322
|
+
if (Array.isArray(previousValue) && current instanceof Y3.Array) {
|
|
199
323
|
syncArrayToYArray(current, previousValue, nextValue);
|
|
200
324
|
} else {
|
|
201
325
|
target.delete(index, 1);
|
|
@@ -204,7 +328,7 @@ function syncArrayToYArray(target, previous, source) {
|
|
|
204
328
|
continue;
|
|
205
329
|
}
|
|
206
330
|
if (isPlainObject(nextValue)) {
|
|
207
|
-
if (isPlainObject(previousValue) && current instanceof
|
|
331
|
+
if (isPlainObject(previousValue) && current instanceof Y3.Map) {
|
|
208
332
|
syncObjectToYMap(current, previousValue, nextValue);
|
|
209
333
|
} else {
|
|
210
334
|
target.delete(index, 1);
|
|
@@ -219,120 +343,11 @@ function syncArrayToYArray(target, previous, source) {
|
|
|
219
343
|
}
|
|
220
344
|
}
|
|
221
345
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
return clone(value);
|
|
228
|
-
}
|
|
229
|
-
return value;
|
|
230
|
-
}
|
|
231
|
-
function toPathKey(path) {
|
|
232
|
-
return path.map((segment) => `${typeof segment}:${String(segment)}`).join("|");
|
|
233
|
-
}
|
|
234
|
-
function compactOperations(operations) {
|
|
235
|
-
const deduplicated = /* @__PURE__ */ new Map();
|
|
236
|
-
for (const operation of operations) {
|
|
237
|
-
const key = toPathKey(operation.path);
|
|
238
|
-
if (deduplicated.has(key)) {
|
|
239
|
-
deduplicated.delete(key);
|
|
240
|
-
}
|
|
241
|
-
deduplicated.set(key, operation);
|
|
242
|
-
}
|
|
243
|
-
return Array.from(deduplicated.values()).sort(
|
|
244
|
-
(left, right) => left.path.length - right.path.length
|
|
245
|
-
);
|
|
246
|
-
}
|
|
247
|
-
function getYValueAtPath(root, path) {
|
|
248
|
-
let current = root;
|
|
249
|
-
for (const segment of path) {
|
|
250
|
-
if (current instanceof Y.Map) {
|
|
251
|
-
current = current.get(String(segment));
|
|
252
|
-
continue;
|
|
253
|
-
}
|
|
254
|
-
if (current instanceof Y.Array) {
|
|
255
|
-
const index = typeof segment === "number" ? segment : Number.parseInt(segment, 10);
|
|
256
|
-
if (!Number.isInteger(index)) {
|
|
257
|
-
return void 0;
|
|
258
|
-
}
|
|
259
|
-
current = current.get(index);
|
|
260
|
-
continue;
|
|
261
|
-
}
|
|
262
|
-
return void 0;
|
|
263
|
-
}
|
|
264
|
-
return current;
|
|
265
|
-
}
|
|
266
|
-
function setAtPath(target, path, value) {
|
|
267
|
-
if (path.length === 0) {
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
let current = target;
|
|
271
|
-
for (let index = 0; index < path.length - 1; index += 1) {
|
|
272
|
-
const segment = path[index];
|
|
273
|
-
const nextSegment = path[index + 1];
|
|
274
|
-
const nextValue = current[segment];
|
|
275
|
-
if (typeof nextValue !== "object" || nextValue === null) {
|
|
276
|
-
current[segment] = typeof nextSegment === "number" ? [] : {};
|
|
277
|
-
}
|
|
278
|
-
current = current[segment];
|
|
279
|
-
}
|
|
280
|
-
const leaf = path[path.length - 1];
|
|
281
|
-
current[leaf] = cloneForStore(value);
|
|
282
|
-
}
|
|
283
|
-
function deleteAtPath(target, path) {
|
|
284
|
-
if (path.length === 0) {
|
|
285
|
-
return;
|
|
286
|
-
}
|
|
287
|
-
let current = target;
|
|
288
|
-
for (let index = 0; index < path.length - 1; index += 1) {
|
|
289
|
-
current = current[path[index]];
|
|
290
|
-
if (typeof current !== "object" || current === null) {
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
const leaf = path[path.length - 1];
|
|
295
|
-
if (Array.isArray(current) && typeof leaf === "number") {
|
|
296
|
-
if (leaf >= 0 && leaf < current.length) {
|
|
297
|
-
current.splice(leaf, 1);
|
|
298
|
-
}
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
|
-
delete current[leaf];
|
|
302
|
-
}
|
|
303
|
-
function collectRemoteOperations(events, stateMap) {
|
|
304
|
-
const operations = [];
|
|
305
|
-
for (const event of events) {
|
|
306
|
-
if (event instanceof Y.YMapEvent) {
|
|
307
|
-
for (const changedKey of event.keysChanged) {
|
|
308
|
-
const path = [...event.path, changedKey];
|
|
309
|
-
const keyChange = event.changes.keys.get(changedKey);
|
|
310
|
-
if (keyChange?.action === "delete") {
|
|
311
|
-
operations.push({
|
|
312
|
-
type: "delete",
|
|
313
|
-
path
|
|
314
|
-
});
|
|
315
|
-
continue;
|
|
316
|
-
}
|
|
317
|
-
operations.push({
|
|
318
|
-
type: "set",
|
|
319
|
-
path,
|
|
320
|
-
value: toPlainValue(getYValueAtPath(stateMap, path))
|
|
321
|
-
});
|
|
322
|
-
}
|
|
323
|
-
continue;
|
|
324
|
-
}
|
|
325
|
-
if (event instanceof Y.YArrayEvent) {
|
|
326
|
-
const path = [...event.path];
|
|
327
|
-
operations.push({
|
|
328
|
-
type: "set",
|
|
329
|
-
path,
|
|
330
|
-
value: toPlainValue(getYValueAtPath(stateMap, path))
|
|
331
|
-
});
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
return operations;
|
|
335
|
-
}
|
|
346
|
+
|
|
347
|
+
// src/index.ts
|
|
348
|
+
__reExport(src_exports, yjs_star);
|
|
349
|
+
import * as yjs_star from "yjs";
|
|
350
|
+
var STATE_KEY = "state";
|
|
336
351
|
var __unsafeTestOnly__ = {
|
|
337
352
|
getYValueAtPath: (root, path) => getYValueAtPath(root, path),
|
|
338
353
|
setAtPath: (target, path, value) => {
|
|
@@ -346,7 +361,7 @@ var bindYjs = (store, options = {}) => {
|
|
|
346
361
|
if (store.share === "client") {
|
|
347
362
|
throw new Error("Yjs binding is not supported in client store mode.");
|
|
348
363
|
}
|
|
349
|
-
const doc = options.doc ?? new
|
|
364
|
+
const doc = options.doc ?? new Y4.Doc();
|
|
350
365
|
const key = options.key ?? `coaction:${store.name}`;
|
|
351
366
|
const map = doc.getMap(key);
|
|
352
367
|
const localOrigin = /* @__PURE__ */ Symbol(`coaction-yjs:${store.name}`);
|
|
@@ -394,7 +409,7 @@ var bindYjs = (store, options = {}) => {
|
|
|
394
409
|
};
|
|
395
410
|
const getStateMap = () => {
|
|
396
411
|
const state = map.get(STATE_KEY);
|
|
397
|
-
if (state instanceof
|
|
412
|
+
if (state instanceof Y4.Map) {
|
|
398
413
|
return state;
|
|
399
414
|
}
|
|
400
415
|
return null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coaction/yjs",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "A Coaction integration tool for Yjs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"state",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"url": "https://github.com/unadlib/coaction/issues"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
|
-
"coaction": "^1.
|
|
41
|
+
"coaction": "^1.5.0",
|
|
42
42
|
"yjs": "^13.6.0"
|
|
43
43
|
},
|
|
44
44
|
"peerDependenciesMeta": {
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"yjs": "^13.6.27",
|
|
54
|
-
"coaction": "1.
|
|
54
|
+
"coaction": "1.5.0"
|
|
55
55
|
},
|
|
56
56
|
"publishConfig": {
|
|
57
57
|
"access": "public",
|