@pluv/crdt-loro 0.35.0 → 0.35.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +8 -8
- package/CHANGELOG.md +9 -0
- package/dist/index.d.mts +11 -24
- package/dist/index.d.ts +11 -24
- package/dist/index.js +50 -33
- package/dist/index.mjs +48 -31
- package/package.json +7 -7
- package/src/doc/CrdtLoroDoc.ts +33 -29
- package/src/loro.ts +2 -0
- package/src/movableList.ts +13 -0
- package/src/tree.ts +7 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @pluv/crdt-loro@0.35.
|
|
2
|
+
> @pluv/crdt-loro@0.35.1 build /home/runner/work/pluv/pluv/packages/crdt-loro
|
|
3
3
|
> tsup src/index.ts --format esm,cjs --dts
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
[34mCLI[39m Target: es6
|
|
9
9
|
[34mESM[39m Build start
|
|
10
10
|
[34mCJS[39m Build start
|
|
11
|
-
[32mCJS[39m [1mdist/index.js [22m[32m9.
|
|
12
|
-
[32mCJS[39m ⚡️ Build success in
|
|
13
|
-
[32mESM[39m [1mdist/index.mjs [22m[32m8.
|
|
14
|
-
[32mESM[39m ⚡️ Build success in
|
|
11
|
+
[32mCJS[39m [1mdist/index.js [22m[32m9.91 KB[39m
|
|
12
|
+
[32mCJS[39m ⚡️ Build success in 129ms
|
|
13
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m8.81 KB[39m
|
|
14
|
+
[32mESM[39m ⚡️ Build success in 131ms
|
|
15
15
|
[34mDTS[39m Build start
|
|
16
|
-
[32mDTS[39m ⚡️ Build success in
|
|
17
|
-
[32mDTS[39m [1mdist/index.d.mts [22m[32m3.
|
|
18
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[32m3.
|
|
16
|
+
[32mDTS[39m ⚡️ Build success in 2274ms
|
|
17
|
+
[32mDTS[39m [1mdist/index.d.mts [22m[32m3.48 KB[39m
|
|
18
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m3.48 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @pluv/crdt-loro
|
|
2
2
|
|
|
3
|
+
## 0.35.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 9822786: Added missing `Tree` and `MovableList` types.
|
|
8
|
+
- 3cd6571: Added support for undo/redo for `@pluv/crdt-loro`.
|
|
9
|
+
- @pluv/crdt@0.35.1
|
|
10
|
+
- @pluv/types@0.35.1
|
|
11
|
+
|
|
3
12
|
## 0.35.0
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CrdtType, AbstractCrdtDoc, DocApplyEncodedStateParams, InferCrdtJson, DocSubscribeCallbackParams, AbstractCrdtDocFactory } from '@pluv/crdt';
|
|
2
|
-
import { LoroDoc, LoroList, LoroMap, LoroText } from 'loro-crdt';
|
|
2
|
+
import { LoroDoc, LoroList, LoroMap, LoroMovableList, LoroText, LoroTree } from 'loro-crdt';
|
|
3
3
|
|
|
4
4
|
type LoroType<TValue extends unknown, TJson extends unknown = any> = TValue & CrdtType<TValue, TJson> & {
|
|
5
5
|
toJSON?: () => any;
|
|
@@ -9,18 +9,11 @@ type LoroType<TValue extends unknown, TJson extends unknown = any> = TValue & Cr
|
|
|
9
9
|
declare class CrdtLoroDoc<TStorage extends Record<string, LoroType<any, any>>> extends AbstractCrdtDoc<TStorage> {
|
|
10
10
|
value: LoroDoc;
|
|
11
11
|
private _storage;
|
|
12
|
+
private _undoManager;
|
|
12
13
|
constructor(value?: TStorage);
|
|
13
14
|
applyEncodedState(params: DocApplyEncodedStateParams): this;
|
|
14
15
|
batchApplyEncodedState(updates: readonly (DocApplyEncodedStateParams | string | null | undefined)[]): this;
|
|
15
|
-
/**
|
|
16
|
-
* TODO
|
|
17
|
-
* @description This method is not yet supported for loro
|
|
18
|
-
*/
|
|
19
16
|
canRedo(): boolean;
|
|
20
|
-
/**
|
|
21
|
-
* TODO
|
|
22
|
-
* @description This method is not yet supported for loro
|
|
23
|
-
*/
|
|
24
17
|
canUndo(): boolean;
|
|
25
18
|
destroy(): void;
|
|
26
19
|
get(key?: undefined): TStorage;
|
|
@@ -29,26 +22,14 @@ declare class CrdtLoroDoc<TStorage extends Record<string, LoroType<any, any>>> e
|
|
|
29
22
|
toJson(): InferCrdtJson<TStorage>;
|
|
30
23
|
toJson<TKey extends keyof TStorage>(type: TKey): InferCrdtJson<TStorage[TKey]>;
|
|
31
24
|
isEmpty(): boolean;
|
|
32
|
-
/**
|
|
33
|
-
* TODO
|
|
34
|
-
* @description This method is not yet supported for loro
|
|
35
|
-
*/
|
|
36
25
|
redo(): this;
|
|
37
26
|
subscribe(listener: (params: DocSubscribeCallbackParams<TStorage>) => void): () => void;
|
|
38
|
-
/**
|
|
39
|
-
* TODO
|
|
40
|
-
* @description This method doesn't do anything yet.
|
|
41
|
-
*/
|
|
42
27
|
track(): this;
|
|
43
28
|
/**
|
|
44
|
-
*
|
|
45
|
-
* @
|
|
29
|
+
* @description Unlike Yjs, this method is required to be called after each loro operation.
|
|
30
|
+
* @date January 12, 2025
|
|
46
31
|
*/
|
|
47
32
|
transact(fn: () => void): this;
|
|
48
|
-
/**
|
|
49
|
-
* TODO
|
|
50
|
-
* @description This method is not yet supported for loro
|
|
51
|
-
*/
|
|
52
33
|
undo(): this;
|
|
53
34
|
}
|
|
54
35
|
|
|
@@ -67,10 +48,14 @@ declare const list: <T extends unknown>(value?: T[] | readonly T[]) => LoroType<
|
|
|
67
48
|
|
|
68
49
|
declare const map: <T extends unknown>(value?: readonly (readonly [key: string, value: T])[]) => LoroType<LoroMap<Record<string, T>>, Record<string, T>>;
|
|
69
50
|
|
|
51
|
+
declare const movableList: <T extends unknown>(value?: T[] | readonly T[]) => LoroType<LoroMovableList<T>, T[]>;
|
|
52
|
+
|
|
70
53
|
declare const object: <T extends Record<string, any>>(value: T) => LoroType<LoroMap<T>, T>;
|
|
71
54
|
|
|
72
55
|
declare const text: (value?: string) => LoroType<LoroText, string>;
|
|
73
56
|
|
|
57
|
+
declare const tree: <T extends Record<string, unknown>>() => LoroTree<T>;
|
|
58
|
+
|
|
74
59
|
declare const kind: "loro";
|
|
75
60
|
|
|
76
61
|
type loro_CrdtLoroDoc<TStorage extends Record<string, LoroType<any, any>>> = CrdtLoroDoc<TStorage>;
|
|
@@ -80,10 +65,12 @@ declare const loro_doc: typeof doc;
|
|
|
80
65
|
declare const loro_kind: typeof kind;
|
|
81
66
|
declare const loro_list: typeof list;
|
|
82
67
|
declare const loro_map: typeof map;
|
|
68
|
+
declare const loro_movableList: typeof movableList;
|
|
83
69
|
declare const loro_object: typeof object;
|
|
84
70
|
declare const loro_text: typeof text;
|
|
71
|
+
declare const loro_tree: typeof tree;
|
|
85
72
|
declare namespace loro {
|
|
86
|
-
export { loro_CrdtLoroDoc as CrdtLoroDoc, type loro_LoroType as LoroType, loro_doc as doc, loro_kind as kind, loro_list as list, loro_map as map, loro_object as object, loro_text as text };
|
|
73
|
+
export { loro_CrdtLoroDoc as CrdtLoroDoc, type loro_LoroType as LoroType, loro_doc as doc, loro_kind as kind, loro_list as list, loro_map as map, loro_movableList as movableList, loro_object as object, loro_text as text, loro_tree as tree };
|
|
87
74
|
}
|
|
88
75
|
|
|
89
76
|
export { loro };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CrdtType, AbstractCrdtDoc, DocApplyEncodedStateParams, InferCrdtJson, DocSubscribeCallbackParams, AbstractCrdtDocFactory } from '@pluv/crdt';
|
|
2
|
-
import { LoroDoc, LoroList, LoroMap, LoroText } from 'loro-crdt';
|
|
2
|
+
import { LoroDoc, LoroList, LoroMap, LoroMovableList, LoroText, LoroTree } from 'loro-crdt';
|
|
3
3
|
|
|
4
4
|
type LoroType<TValue extends unknown, TJson extends unknown = any> = TValue & CrdtType<TValue, TJson> & {
|
|
5
5
|
toJSON?: () => any;
|
|
@@ -9,18 +9,11 @@ type LoroType<TValue extends unknown, TJson extends unknown = any> = TValue & Cr
|
|
|
9
9
|
declare class CrdtLoroDoc<TStorage extends Record<string, LoroType<any, any>>> extends AbstractCrdtDoc<TStorage> {
|
|
10
10
|
value: LoroDoc;
|
|
11
11
|
private _storage;
|
|
12
|
+
private _undoManager;
|
|
12
13
|
constructor(value?: TStorage);
|
|
13
14
|
applyEncodedState(params: DocApplyEncodedStateParams): this;
|
|
14
15
|
batchApplyEncodedState(updates: readonly (DocApplyEncodedStateParams | string | null | undefined)[]): this;
|
|
15
|
-
/**
|
|
16
|
-
* TODO
|
|
17
|
-
* @description This method is not yet supported for loro
|
|
18
|
-
*/
|
|
19
16
|
canRedo(): boolean;
|
|
20
|
-
/**
|
|
21
|
-
* TODO
|
|
22
|
-
* @description This method is not yet supported for loro
|
|
23
|
-
*/
|
|
24
17
|
canUndo(): boolean;
|
|
25
18
|
destroy(): void;
|
|
26
19
|
get(key?: undefined): TStorage;
|
|
@@ -29,26 +22,14 @@ declare class CrdtLoroDoc<TStorage extends Record<string, LoroType<any, any>>> e
|
|
|
29
22
|
toJson(): InferCrdtJson<TStorage>;
|
|
30
23
|
toJson<TKey extends keyof TStorage>(type: TKey): InferCrdtJson<TStorage[TKey]>;
|
|
31
24
|
isEmpty(): boolean;
|
|
32
|
-
/**
|
|
33
|
-
* TODO
|
|
34
|
-
* @description This method is not yet supported for loro
|
|
35
|
-
*/
|
|
36
25
|
redo(): this;
|
|
37
26
|
subscribe(listener: (params: DocSubscribeCallbackParams<TStorage>) => void): () => void;
|
|
38
|
-
/**
|
|
39
|
-
* TODO
|
|
40
|
-
* @description This method doesn't do anything yet.
|
|
41
|
-
*/
|
|
42
27
|
track(): this;
|
|
43
28
|
/**
|
|
44
|
-
*
|
|
45
|
-
* @
|
|
29
|
+
* @description Unlike Yjs, this method is required to be called after each loro operation.
|
|
30
|
+
* @date January 12, 2025
|
|
46
31
|
*/
|
|
47
32
|
transact(fn: () => void): this;
|
|
48
|
-
/**
|
|
49
|
-
* TODO
|
|
50
|
-
* @description This method is not yet supported for loro
|
|
51
|
-
*/
|
|
52
33
|
undo(): this;
|
|
53
34
|
}
|
|
54
35
|
|
|
@@ -67,10 +48,14 @@ declare const list: <T extends unknown>(value?: T[] | readonly T[]) => LoroType<
|
|
|
67
48
|
|
|
68
49
|
declare const map: <T extends unknown>(value?: readonly (readonly [key: string, value: T])[]) => LoroType<LoroMap<Record<string, T>>, Record<string, T>>;
|
|
69
50
|
|
|
51
|
+
declare const movableList: <T extends unknown>(value?: T[] | readonly T[]) => LoroType<LoroMovableList<T>, T[]>;
|
|
52
|
+
|
|
70
53
|
declare const object: <T extends Record<string, any>>(value: T) => LoroType<LoroMap<T>, T>;
|
|
71
54
|
|
|
72
55
|
declare const text: (value?: string) => LoroType<LoroText, string>;
|
|
73
56
|
|
|
57
|
+
declare const tree: <T extends Record<string, unknown>>() => LoroTree<T>;
|
|
58
|
+
|
|
74
59
|
declare const kind: "loro";
|
|
75
60
|
|
|
76
61
|
type loro_CrdtLoroDoc<TStorage extends Record<string, LoroType<any, any>>> = CrdtLoroDoc<TStorage>;
|
|
@@ -80,10 +65,12 @@ declare const loro_doc: typeof doc;
|
|
|
80
65
|
declare const loro_kind: typeof kind;
|
|
81
66
|
declare const loro_list: typeof list;
|
|
82
67
|
declare const loro_map: typeof map;
|
|
68
|
+
declare const loro_movableList: typeof movableList;
|
|
83
69
|
declare const loro_object: typeof object;
|
|
84
70
|
declare const loro_text: typeof text;
|
|
71
|
+
declare const loro_tree: typeof tree;
|
|
85
72
|
declare namespace loro {
|
|
86
|
-
export { loro_CrdtLoroDoc as CrdtLoroDoc, type loro_LoroType as LoroType, loro_doc as doc, loro_kind as kind, loro_list as list, loro_map as map, loro_object as object, loro_text as text };
|
|
73
|
+
export { loro_CrdtLoroDoc as CrdtLoroDoc, type loro_LoroType as LoroType, loro_doc as doc, loro_kind as kind, loro_list as list, loro_map as map, loro_movableList as movableList, loro_object as object, loro_text as text, loro_tree as tree };
|
|
87
74
|
}
|
|
88
75
|
|
|
89
76
|
export { loro };
|
package/dist/index.js
CHANGED
|
@@ -49,18 +49,23 @@ __export(loro_exports, {
|
|
|
49
49
|
kind: () => kind,
|
|
50
50
|
list: () => list,
|
|
51
51
|
map: () => map,
|
|
52
|
+
movableList: () => movableList,
|
|
52
53
|
object: () => object,
|
|
53
|
-
text: () => text
|
|
54
|
+
text: () => text,
|
|
55
|
+
tree: () => tree
|
|
54
56
|
});
|
|
55
57
|
|
|
56
58
|
// src/doc/CrdtLoroDoc.ts
|
|
57
59
|
var import_crdt = require("@pluv/crdt");
|
|
58
60
|
var import_js_base64 = require("js-base64");
|
|
59
61
|
var import_loro_crdt = require("loro-crdt");
|
|
62
|
+
var MAX_UNDO_STEPS = 100;
|
|
63
|
+
var MERGE_INTERVAL_MS = 1e3;
|
|
60
64
|
var CrdtLoroDoc = class extends import_crdt.AbstractCrdtDoc {
|
|
61
65
|
constructor(value = {}) {
|
|
62
66
|
super();
|
|
63
67
|
this.value = new import_loro_crdt.LoroDoc();
|
|
68
|
+
this._undoManager = null;
|
|
64
69
|
this._storage = Object.entries(value).reduce((acc, [key, node]) => {
|
|
65
70
|
if (node instanceof import_loro_crdt.LoroList) {
|
|
66
71
|
const container = this.value.getList(key);
|
|
@@ -112,22 +117,16 @@ var CrdtLoroDoc = class extends import_crdt.AbstractCrdtDoc {
|
|
|
112
117
|
update && this.value.import(update);
|
|
113
118
|
return this;
|
|
114
119
|
}
|
|
115
|
-
this.value.
|
|
120
|
+
this.value.importBatch(_updates);
|
|
116
121
|
return this;
|
|
117
122
|
}
|
|
118
|
-
/**
|
|
119
|
-
* TODO
|
|
120
|
-
* @description This method is not yet supported for loro
|
|
121
|
-
*/
|
|
122
123
|
canRedo() {
|
|
123
|
-
return false;
|
|
124
|
+
if (!this._undoManager) return false;
|
|
125
|
+
return this._undoManager.canRedo();
|
|
124
126
|
}
|
|
125
|
-
/**
|
|
126
|
-
* TODO
|
|
127
|
-
* @description This method is not yet supported for loro
|
|
128
|
-
*/
|
|
129
127
|
canUndo() {
|
|
130
|
-
return false;
|
|
128
|
+
if (!this._undoManager) return false;
|
|
129
|
+
return this._undoManager.canUndo();
|
|
131
130
|
}
|
|
132
131
|
destroy() {
|
|
133
132
|
return;
|
|
@@ -155,12 +154,10 @@ var CrdtLoroDoc = class extends import_crdt.AbstractCrdtDoc {
|
|
|
155
154
|
const serialized = this.value.toJSON();
|
|
156
155
|
return !serialized || !Object.keys(serialized).length;
|
|
157
156
|
}
|
|
158
|
-
/**
|
|
159
|
-
* TODO
|
|
160
|
-
* @description This method is not yet supported for loro
|
|
161
|
-
*/
|
|
162
157
|
redo() {
|
|
163
|
-
|
|
158
|
+
var _a;
|
|
159
|
+
(_a = this._undoManager) == null ? void 0 : _a.redo();
|
|
160
|
+
return this;
|
|
164
161
|
}
|
|
165
162
|
subscribe(listener) {
|
|
166
163
|
const fn = (event) => {
|
|
@@ -185,28 +182,31 @@ var CrdtLoroDoc = class extends import_crdt.AbstractCrdtDoc {
|
|
|
185
182
|
);
|
|
186
183
|
return unsubcribeAll;
|
|
187
184
|
}
|
|
188
|
-
/**
|
|
189
|
-
* TODO
|
|
190
|
-
* @description This method doesn't do anything yet.
|
|
191
|
-
*/
|
|
192
185
|
track() {
|
|
186
|
+
if (this._undoManager) {
|
|
187
|
+
this._undoManager.clear();
|
|
188
|
+
this._undoManager.free();
|
|
189
|
+
this._undoManager = null;
|
|
190
|
+
}
|
|
191
|
+
this._undoManager = new import_loro_crdt.UndoManager(this.value, {
|
|
192
|
+
maxUndoSteps: MAX_UNDO_STEPS,
|
|
193
|
+
mergeInterval: MERGE_INTERVAL_MS
|
|
194
|
+
});
|
|
193
195
|
return this;
|
|
194
196
|
}
|
|
195
197
|
/**
|
|
196
|
-
*
|
|
197
|
-
* @
|
|
198
|
+
* @description Unlike Yjs, this method is required to be called after each loro operation.
|
|
199
|
+
* @date January 12, 2025
|
|
198
200
|
*/
|
|
199
201
|
transact(fn) {
|
|
200
202
|
fn();
|
|
201
203
|
this.value.commit();
|
|
202
204
|
return this;
|
|
203
205
|
}
|
|
204
|
-
/**
|
|
205
|
-
* TODO
|
|
206
|
-
* @description This method is not yet supported for loro
|
|
207
|
-
*/
|
|
208
206
|
undo() {
|
|
209
|
-
|
|
207
|
+
var _a;
|
|
208
|
+
(_a = this._undoManager) == null ? void 0 : _a.undo();
|
|
209
|
+
return this;
|
|
210
210
|
}
|
|
211
211
|
};
|
|
212
212
|
|
|
@@ -272,24 +272,41 @@ var map = (value = []) => {
|
|
|
272
272
|
return container;
|
|
273
273
|
};
|
|
274
274
|
|
|
275
|
-
// src/
|
|
275
|
+
// src/movableList.ts
|
|
276
276
|
var import_loro_crdt5 = require("loro-crdt");
|
|
277
|
+
var movableList = (value = []) => {
|
|
278
|
+
const container = new import_loro_crdt5.LoroMovableList();
|
|
279
|
+
value.forEach((item, i) => {
|
|
280
|
+
(0, import_loro_crdt5.isContainer)(item) ? container.insertContainer(i, item) : container.insert(i, item);
|
|
281
|
+
});
|
|
282
|
+
return container;
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
// src/object.ts
|
|
286
|
+
var import_loro_crdt6 = require("loro-crdt");
|
|
277
287
|
var object = (value) => {
|
|
278
|
-
const container = new
|
|
288
|
+
const container = new import_loro_crdt6.LoroMap();
|
|
279
289
|
Object.entries(value).forEach(([key, item]) => {
|
|
280
|
-
(0,
|
|
290
|
+
(0, import_loro_crdt6.isContainer)(item) ? container.setContainer(key, item) : container.set(key, item);
|
|
281
291
|
});
|
|
282
292
|
return container;
|
|
283
293
|
};
|
|
284
294
|
|
|
285
295
|
// src/text.ts
|
|
286
|
-
var
|
|
296
|
+
var import_loro_crdt7 = require("loro-crdt");
|
|
287
297
|
var text = (value = "") => {
|
|
288
|
-
const container = new
|
|
298
|
+
const container = new import_loro_crdt7.LoroText();
|
|
289
299
|
container.insert(0, value);
|
|
290
300
|
return container;
|
|
291
301
|
};
|
|
292
302
|
|
|
303
|
+
// src/tree.ts
|
|
304
|
+
var import_loro_crdt8 = require("loro-crdt");
|
|
305
|
+
var tree = () => {
|
|
306
|
+
const container = new import_loro_crdt8.LoroTree();
|
|
307
|
+
return container;
|
|
308
|
+
};
|
|
309
|
+
|
|
293
310
|
// src/loro.ts
|
|
294
311
|
var kind = "loro";
|
|
295
312
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/index.mjs
CHANGED
|
@@ -30,18 +30,23 @@ __export(loro_exports, {
|
|
|
30
30
|
kind: () => kind,
|
|
31
31
|
list: () => list,
|
|
32
32
|
map: () => map,
|
|
33
|
+
movableList: () => movableList,
|
|
33
34
|
object: () => object,
|
|
34
|
-
text: () => text
|
|
35
|
+
text: () => text,
|
|
36
|
+
tree: () => tree
|
|
35
37
|
});
|
|
36
38
|
|
|
37
39
|
// src/doc/CrdtLoroDoc.ts
|
|
38
40
|
import { AbstractCrdtDoc } from "@pluv/crdt";
|
|
39
41
|
import { fromUint8Array, toUint8Array } from "js-base64";
|
|
40
|
-
import { LoroDoc, LoroList, LoroMap, LoroText, isContainer } from "loro-crdt";
|
|
42
|
+
import { LoroDoc, LoroList, LoroMap, LoroText, UndoManager, isContainer } from "loro-crdt";
|
|
43
|
+
var MAX_UNDO_STEPS = 100;
|
|
44
|
+
var MERGE_INTERVAL_MS = 1e3;
|
|
41
45
|
var CrdtLoroDoc = class extends AbstractCrdtDoc {
|
|
42
46
|
constructor(value = {}) {
|
|
43
47
|
super();
|
|
44
48
|
this.value = new LoroDoc();
|
|
49
|
+
this._undoManager = null;
|
|
45
50
|
this._storage = Object.entries(value).reduce((acc, [key, node]) => {
|
|
46
51
|
if (node instanceof LoroList) {
|
|
47
52
|
const container = this.value.getList(key);
|
|
@@ -93,22 +98,16 @@ var CrdtLoroDoc = class extends AbstractCrdtDoc {
|
|
|
93
98
|
update && this.value.import(update);
|
|
94
99
|
return this;
|
|
95
100
|
}
|
|
96
|
-
this.value.
|
|
101
|
+
this.value.importBatch(_updates);
|
|
97
102
|
return this;
|
|
98
103
|
}
|
|
99
|
-
/**
|
|
100
|
-
* TODO
|
|
101
|
-
* @description This method is not yet supported for loro
|
|
102
|
-
*/
|
|
103
104
|
canRedo() {
|
|
104
|
-
return false;
|
|
105
|
+
if (!this._undoManager) return false;
|
|
106
|
+
return this._undoManager.canRedo();
|
|
105
107
|
}
|
|
106
|
-
/**
|
|
107
|
-
* TODO
|
|
108
|
-
* @description This method is not yet supported for loro
|
|
109
|
-
*/
|
|
110
108
|
canUndo() {
|
|
111
|
-
return false;
|
|
109
|
+
if (!this._undoManager) return false;
|
|
110
|
+
return this._undoManager.canUndo();
|
|
112
111
|
}
|
|
113
112
|
destroy() {
|
|
114
113
|
return;
|
|
@@ -136,12 +135,10 @@ var CrdtLoroDoc = class extends AbstractCrdtDoc {
|
|
|
136
135
|
const serialized = this.value.toJSON();
|
|
137
136
|
return !serialized || !Object.keys(serialized).length;
|
|
138
137
|
}
|
|
139
|
-
/**
|
|
140
|
-
* TODO
|
|
141
|
-
* @description This method is not yet supported for loro
|
|
142
|
-
*/
|
|
143
138
|
redo() {
|
|
144
|
-
|
|
139
|
+
var _a;
|
|
140
|
+
(_a = this._undoManager) == null ? void 0 : _a.redo();
|
|
141
|
+
return this;
|
|
145
142
|
}
|
|
146
143
|
subscribe(listener) {
|
|
147
144
|
const fn = (event) => {
|
|
@@ -166,28 +163,31 @@ var CrdtLoroDoc = class extends AbstractCrdtDoc {
|
|
|
166
163
|
);
|
|
167
164
|
return unsubcribeAll;
|
|
168
165
|
}
|
|
169
|
-
/**
|
|
170
|
-
* TODO
|
|
171
|
-
* @description This method doesn't do anything yet.
|
|
172
|
-
*/
|
|
173
166
|
track() {
|
|
167
|
+
if (this._undoManager) {
|
|
168
|
+
this._undoManager.clear();
|
|
169
|
+
this._undoManager.free();
|
|
170
|
+
this._undoManager = null;
|
|
171
|
+
}
|
|
172
|
+
this._undoManager = new UndoManager(this.value, {
|
|
173
|
+
maxUndoSteps: MAX_UNDO_STEPS,
|
|
174
|
+
mergeInterval: MERGE_INTERVAL_MS
|
|
175
|
+
});
|
|
174
176
|
return this;
|
|
175
177
|
}
|
|
176
178
|
/**
|
|
177
|
-
*
|
|
178
|
-
* @
|
|
179
|
+
* @description Unlike Yjs, this method is required to be called after each loro operation.
|
|
180
|
+
* @date January 12, 2025
|
|
179
181
|
*/
|
|
180
182
|
transact(fn) {
|
|
181
183
|
fn();
|
|
182
184
|
this.value.commit();
|
|
183
185
|
return this;
|
|
184
186
|
}
|
|
185
|
-
/**
|
|
186
|
-
* TODO
|
|
187
|
-
* @description This method is not yet supported for loro
|
|
188
|
-
*/
|
|
189
187
|
undo() {
|
|
190
|
-
|
|
188
|
+
var _a;
|
|
189
|
+
(_a = this._undoManager) == null ? void 0 : _a.undo();
|
|
190
|
+
return this;
|
|
191
191
|
}
|
|
192
192
|
};
|
|
193
193
|
|
|
@@ -253,12 +253,22 @@ var map = (value = []) => {
|
|
|
253
253
|
return container;
|
|
254
254
|
};
|
|
255
255
|
|
|
256
|
+
// src/movableList.ts
|
|
257
|
+
import { isContainer as isContainer4, LoroMovableList } from "loro-crdt";
|
|
258
|
+
var movableList = (value = []) => {
|
|
259
|
+
const container = new LoroMovableList();
|
|
260
|
+
value.forEach((item, i) => {
|
|
261
|
+
isContainer4(item) ? container.insertContainer(i, item) : container.insert(i, item);
|
|
262
|
+
});
|
|
263
|
+
return container;
|
|
264
|
+
};
|
|
265
|
+
|
|
256
266
|
// src/object.ts
|
|
257
|
-
import { LoroMap as LoroMap4, isContainer as
|
|
267
|
+
import { LoroMap as LoroMap4, isContainer as isContainer5 } from "loro-crdt";
|
|
258
268
|
var object = (value) => {
|
|
259
269
|
const container = new LoroMap4();
|
|
260
270
|
Object.entries(value).forEach(([key, item]) => {
|
|
261
|
-
|
|
271
|
+
isContainer5(item) ? container.setContainer(key, item) : container.set(key, item);
|
|
262
272
|
});
|
|
263
273
|
return container;
|
|
264
274
|
};
|
|
@@ -271,6 +281,13 @@ var text = (value = "") => {
|
|
|
271
281
|
return container;
|
|
272
282
|
};
|
|
273
283
|
|
|
284
|
+
// src/tree.ts
|
|
285
|
+
import { LoroTree } from "loro-crdt";
|
|
286
|
+
var tree = () => {
|
|
287
|
+
const container = new LoroTree();
|
|
288
|
+
return container;
|
|
289
|
+
};
|
|
290
|
+
|
|
274
291
|
// src/loro.ts
|
|
275
292
|
var kind = "loro";
|
|
276
293
|
export {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pluv/crdt-loro",
|
|
3
|
-
"version": "0.35.
|
|
3
|
+
"version": "0.35.1",
|
|
4
4
|
"description": "loro for @pluv/io",
|
|
5
5
|
"author": "leedavidcs",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,19 +18,19 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"js-base64": "^3.7.7",
|
|
21
|
-
"@pluv/crdt": "^0.35.
|
|
22
|
-
"@pluv/types": "^0.35.
|
|
21
|
+
"@pluv/crdt": "^0.35.1",
|
|
22
|
+
"@pluv/types": "^0.35.1"
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|
|
25
25
|
"loro-crdt": "^1.0.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"eslint": "^8.57.1",
|
|
29
|
-
"loro-crdt": "^1.
|
|
29
|
+
"loro-crdt": "^1.3.1",
|
|
30
30
|
"tsup": "^8.3.5",
|
|
31
|
-
"typescript": "^5.7.
|
|
32
|
-
"@pluv/tsconfig": "^0.35.
|
|
33
|
-
"eslint-config-pluv": "^0.35.
|
|
31
|
+
"typescript": "^5.7.3",
|
|
32
|
+
"@pluv/tsconfig": "^0.35.1",
|
|
33
|
+
"eslint-config-pluv": "^0.35.1"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
36
|
"build": "tsup src/index.ts --format esm,cjs --dts",
|
package/src/doc/CrdtLoroDoc.ts
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import type { DocApplyEncodedStateParams, DocSubscribeCallbackParams, InferCrdtJson } from "@pluv/crdt";
|
|
2
2
|
import { AbstractCrdtDoc } from "@pluv/crdt";
|
|
3
3
|
import { fromUint8Array, toUint8Array } from "js-base64";
|
|
4
|
-
import type { Container
|
|
5
|
-
import { LoroDoc, LoroList, LoroMap, LoroText, isContainer } from "loro-crdt";
|
|
4
|
+
import type { Container } from "loro-crdt";
|
|
5
|
+
import { LoroDoc, LoroEventBatch, LoroList, LoroMap, LoroText, UndoManager, isContainer } from "loro-crdt";
|
|
6
6
|
import type { LoroType } from "../types";
|
|
7
7
|
|
|
8
|
+
const MAX_UNDO_STEPS = 100;
|
|
9
|
+
const MERGE_INTERVAL_MS = 1_000;
|
|
10
|
+
|
|
8
11
|
export class CrdtLoroDoc<TStorage extends Record<string, LoroType<any, any>>> extends AbstractCrdtDoc<TStorage> {
|
|
9
12
|
public value: LoroDoc = new LoroDoc();
|
|
10
13
|
|
|
11
14
|
private _storage: TStorage;
|
|
15
|
+
private _undoManager: UndoManager | null = null;
|
|
12
16
|
|
|
13
17
|
constructor(value: TStorage = {} as TStorage) {
|
|
14
18
|
super();
|
|
@@ -89,25 +93,21 @@ export class CrdtLoroDoc<TStorage extends Record<string, LoroType<any, any>>> ex
|
|
|
89
93
|
return this;
|
|
90
94
|
}
|
|
91
95
|
|
|
92
|
-
this.value.
|
|
96
|
+
this.value.importBatch(_updates);
|
|
93
97
|
|
|
94
98
|
return this;
|
|
95
99
|
}
|
|
96
100
|
|
|
97
|
-
/**
|
|
98
|
-
* TODO
|
|
99
|
-
* @description This method is not yet supported for loro
|
|
100
|
-
*/
|
|
101
101
|
public canRedo(): boolean {
|
|
102
|
-
return false;
|
|
102
|
+
if (!this._undoManager) return false;
|
|
103
|
+
|
|
104
|
+
return this._undoManager.canRedo();
|
|
103
105
|
}
|
|
104
106
|
|
|
105
|
-
/**
|
|
106
|
-
* TODO
|
|
107
|
-
* @description This method is not yet supported for loro
|
|
108
|
-
*/
|
|
109
107
|
public canUndo(): boolean {
|
|
110
|
-
return false;
|
|
108
|
+
if (!this._undoManager) return false;
|
|
109
|
+
|
|
110
|
+
return this._undoManager.canUndo();
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
public destroy(): void {
|
|
@@ -150,12 +150,10 @@ export class CrdtLoroDoc<TStorage extends Record<string, LoroType<any, any>>> ex
|
|
|
150
150
|
return !serialized || !Object.keys(serialized).length;
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
/**
|
|
154
|
-
* TODO
|
|
155
|
-
* @description This method is not yet supported for loro
|
|
156
|
-
*/
|
|
157
153
|
public redo(): this {
|
|
158
|
-
|
|
154
|
+
this._undoManager?.redo();
|
|
155
|
+
|
|
156
|
+
return this;
|
|
159
157
|
}
|
|
160
158
|
|
|
161
159
|
public subscribe(listener: (params: DocSubscribeCallbackParams<TStorage>) => void): () => void {
|
|
@@ -186,17 +184,25 @@ export class CrdtLoroDoc<TStorage extends Record<string, LoroType<any, any>>> ex
|
|
|
186
184
|
return unsubcribeAll;
|
|
187
185
|
}
|
|
188
186
|
|
|
189
|
-
/**
|
|
190
|
-
* TODO
|
|
191
|
-
* @description This method doesn't do anything yet.
|
|
192
|
-
*/
|
|
193
187
|
public track(): this {
|
|
188
|
+
if (this._undoManager) {
|
|
189
|
+
this._undoManager.clear();
|
|
190
|
+
this._undoManager.free();
|
|
191
|
+
|
|
192
|
+
this._undoManager = null;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
this._undoManager = new UndoManager(this.value, {
|
|
196
|
+
maxUndoSteps: MAX_UNDO_STEPS,
|
|
197
|
+
mergeInterval: MERGE_INTERVAL_MS,
|
|
198
|
+
});
|
|
199
|
+
|
|
194
200
|
return this;
|
|
195
201
|
}
|
|
196
202
|
|
|
197
203
|
/**
|
|
198
|
-
*
|
|
199
|
-
* @
|
|
204
|
+
* @description Unlike Yjs, this method is required to be called after each loro operation.
|
|
205
|
+
* @date January 12, 2025
|
|
200
206
|
*/
|
|
201
207
|
public transact(fn: () => void): this {
|
|
202
208
|
fn();
|
|
@@ -206,11 +212,9 @@ export class CrdtLoroDoc<TStorage extends Record<string, LoroType<any, any>>> ex
|
|
|
206
212
|
return this;
|
|
207
213
|
}
|
|
208
214
|
|
|
209
|
-
/**
|
|
210
|
-
* TODO
|
|
211
|
-
* @description This method is not yet supported for loro
|
|
212
|
-
*/
|
|
213
215
|
public undo(): this {
|
|
214
|
-
|
|
216
|
+
this._undoManager?.undo();
|
|
217
|
+
|
|
218
|
+
return this;
|
|
215
219
|
}
|
|
216
220
|
}
|
package/src/loro.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export { CrdtLoroDoc, doc } from "./doc";
|
|
2
2
|
export { list } from "./list";
|
|
3
3
|
export { map } from "./map";
|
|
4
|
+
export { movableList } from "./movableList";
|
|
4
5
|
export { object } from "./object";
|
|
5
6
|
export { text } from "./text";
|
|
7
|
+
export { tree } from "./tree";
|
|
6
8
|
export type { LoroType } from "./types";
|
|
7
9
|
export const kind = "loro" as const;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Container } from "loro-crdt";
|
|
2
|
+
import { isContainer, LoroMovableList } from "loro-crdt";
|
|
3
|
+
import type { LoroType } from "./types";
|
|
4
|
+
|
|
5
|
+
export const movableList = <T extends unknown>(value: T[] | readonly T[] = []) => {
|
|
6
|
+
const container = new LoroMovableList();
|
|
7
|
+
|
|
8
|
+
value.forEach((item, i) => {
|
|
9
|
+
isContainer(item) ? container.insertContainer(i, item) : container.insert(i, item as Exclude<T, Container>);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
return container as unknown as LoroType<LoroMovableList<T>, T[]>;
|
|
13
|
+
};
|