@pluv/crdt-loro 0.19.0 → 0.21.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/.turbo/turbo-build.log +15 -15
- package/CHANGELOG.md +84 -0
- package/dist/index.d.mts +24 -102
- package/dist/index.d.ts +24 -102
- package/dist/index.js +84 -448
- package/dist/index.mjs +79 -443
- package/package.json +9 -9
- package/src/doc/CrdtLoroDoc.ts +43 -39
- package/src/doc/CrdtLoroDocFactory.ts +9 -16
- package/src/doc/doc.ts +2 -2
- package/src/list.ts +13 -0
- package/src/loro.ts +5 -5
- package/src/map.ts +15 -0
- package/src/object.ts +13 -0
- package/src/text.ts +10 -0
- package/src/types.ts +6 -39
- package/src/array/CrdtLoroArray.ts +0 -96
- package/src/array/array.ts +0 -5
- package/src/array/index.ts +0 -2
- package/src/map/CrdtLoroMap.ts +0 -88
- package/src/map/index.ts +0 -2
- package/src/map/map.ts +0 -5
- package/src/object/CrdtLoroObject.ts +0 -75
- package/src/object/index.ts +0 -2
- package/src/object/object.ts +0 -5
- package/src/shared/cloneType.ts +0 -234
- package/src/shared/getLoroContainerType.ts +0 -22
- package/src/shared/index.ts +0 -5
- package/src/shared/isWrapper.ts +0 -15
- package/src/shared/toLoroValue.ts +0 -5
- package/src/text/CrdtLoroText.ts +0 -68
- package/src/text/index.ts +0 -2
- package/src/text/text.ts +0 -5
package/src/doc/CrdtLoroDoc.ts
CHANGED
|
@@ -1,21 +1,11 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
AbstractCrdtType,
|
|
3
|
-
DocApplyEncodedStateParams,
|
|
4
|
-
DocSubscribeCallbackParams,
|
|
5
|
-
InferCrdtStorageJson,
|
|
6
|
-
} from "@pluv/crdt";
|
|
1
|
+
import type { DocApplyEncodedStateParams, DocSubscribeCallbackParams, InferCrdtJson } from "@pluv/crdt";
|
|
7
2
|
import { AbstractCrdtDoc } from "@pluv/crdt";
|
|
8
3
|
import { fromUint8Array, toUint8Array } from "js-base64";
|
|
9
4
|
import type { Container, LoroEventBatch } from "loro-crdt";
|
|
10
|
-
import { Loro } from "loro-crdt";
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
import { CrdtLoroText } from "../text/CrdtLoroText";
|
|
15
|
-
|
|
16
|
-
export class CrdtLoroDoc<
|
|
17
|
-
TStorage extends Record<string, AbstractCrdtType<any, any>>,
|
|
18
|
-
> extends AbstractCrdtDoc<TStorage> {
|
|
5
|
+
import { Loro, LoroList, LoroMap, LoroText, isContainer } from "loro-crdt";
|
|
6
|
+
import { LoroType } from "../types";
|
|
7
|
+
|
|
8
|
+
export class CrdtLoroDoc<TStorage extends Record<string, LoroType<any, any>>> extends AbstractCrdtDoc<TStorage> {
|
|
19
9
|
public value: Loro = new Loro();
|
|
20
10
|
|
|
21
11
|
private _storage: TStorage;
|
|
@@ -24,31 +14,32 @@ export class CrdtLoroDoc<
|
|
|
24
14
|
super();
|
|
25
15
|
|
|
26
16
|
this._storage = Object.entries(value).reduce((acc, [key, node]) => {
|
|
27
|
-
if (node instanceof
|
|
28
|
-
const
|
|
17
|
+
if (node instanceof LoroList) {
|
|
18
|
+
const container = this.value.getList(key);
|
|
29
19
|
|
|
30
|
-
node.
|
|
31
|
-
|
|
20
|
+
node.toArray().forEach((item, i) => {
|
|
21
|
+
isContainer(item) ? container.insertContainer(i, item) : container.insert(i, item);
|
|
22
|
+
});
|
|
32
23
|
|
|
33
|
-
return { ...acc, [key]:
|
|
24
|
+
return { ...acc, [key]: container };
|
|
34
25
|
}
|
|
35
26
|
|
|
36
|
-
if (node instanceof
|
|
37
|
-
const
|
|
27
|
+
if (node instanceof LoroMap) {
|
|
28
|
+
const container = this.value.getMap(key);
|
|
38
29
|
|
|
39
|
-
|
|
40
|
-
|
|
30
|
+
container.entries().forEach(([key, item]) => {
|
|
31
|
+
isContainer(item) ? container.setContainer(key, item) : container.set(key, item);
|
|
32
|
+
});
|
|
41
33
|
|
|
42
|
-
return { ...acc, [key]:
|
|
34
|
+
return { ...acc, [key]: container };
|
|
43
35
|
}
|
|
44
36
|
|
|
45
|
-
if (node instanceof
|
|
46
|
-
const
|
|
37
|
+
if (node instanceof LoroText) {
|
|
38
|
+
const container = this.value.getText(key);
|
|
47
39
|
|
|
48
|
-
node.
|
|
49
|
-
node.doc = this;
|
|
40
|
+
container.insert(0, node.toString());
|
|
50
41
|
|
|
51
|
-
return { ...acc, [key]:
|
|
42
|
+
return { ...acc, [key]: container };
|
|
52
43
|
}
|
|
53
44
|
|
|
54
45
|
return acc;
|
|
@@ -135,15 +126,26 @@ export class CrdtLoroDoc<
|
|
|
135
126
|
return fromUint8Array(this.value.exportSnapshot());
|
|
136
127
|
}
|
|
137
128
|
|
|
138
|
-
public toJson():
|
|
129
|
+
public toJson(): InferCrdtJson<TStorage>;
|
|
130
|
+
public toJson<TKey extends keyof TStorage>(type: TKey): InferCrdtJson<TStorage[TKey]>;
|
|
131
|
+
public toJson<TKey extends keyof TStorage>(type?: TKey) {
|
|
132
|
+
if (typeof type === "string") {
|
|
133
|
+
const container = this._storage[type] as unknown as Container;
|
|
134
|
+
|
|
135
|
+
return container instanceof LoroText ? container.toString() : container.toJSON!();
|
|
136
|
+
}
|
|
137
|
+
|
|
139
138
|
return Object.entries(this._storage).reduce(
|
|
140
|
-
(acc, [key, value]) => ({
|
|
141
|
-
|
|
139
|
+
(acc, [key, value]) => ({
|
|
140
|
+
...(acc as any),
|
|
141
|
+
[key]: value instanceof LoroText ? value.toString() : value.toJSON!(),
|
|
142
|
+
}),
|
|
143
|
+
{} as InferCrdtJson<TStorage>,
|
|
142
144
|
);
|
|
143
145
|
}
|
|
144
146
|
|
|
145
147
|
public isEmpty(): boolean {
|
|
146
|
-
const serialized = this.value.
|
|
148
|
+
const serialized = this.value.toJSON();
|
|
147
149
|
|
|
148
150
|
return !serialized || !Object.keys(serialized).length;
|
|
149
151
|
}
|
|
@@ -162,28 +164,28 @@ export class CrdtLoroDoc<
|
|
|
162
164
|
|
|
163
165
|
listener({
|
|
164
166
|
doc: this,
|
|
165
|
-
local: event.local,
|
|
167
|
+
local: event.by === "local",
|
|
166
168
|
origin: event.origin ? String(event.origin) : null,
|
|
167
169
|
update,
|
|
168
170
|
});
|
|
169
171
|
};
|
|
170
172
|
|
|
171
173
|
const subscriptionIds = Object.entries(this._storage).reduce((map, [key, crdtType]) => {
|
|
172
|
-
const container = crdtType
|
|
173
|
-
const subscriptionId = container.subscribe(
|
|
174
|
+
const container = crdtType as unknown as Container;
|
|
175
|
+
const subscriptionId = container.subscribe(fn);
|
|
174
176
|
|
|
175
177
|
return map.set(key, subscriptionId);
|
|
176
178
|
}, new Map<string, number>());
|
|
177
179
|
|
|
178
180
|
return () => {
|
|
179
181
|
Array.from(subscriptionIds.entries()).forEach(([key, subscriptionId]) => {
|
|
180
|
-
const container = (this._storage[key]
|
|
182
|
+
const container = (this._storage[key] ?? null) as unknown as Container | null;
|
|
181
183
|
|
|
182
184
|
if (!container) {
|
|
183
185
|
throw new Error("Storage could not be found");
|
|
184
186
|
}
|
|
185
187
|
|
|
186
|
-
container.unsubscribe(
|
|
188
|
+
container.unsubscribe(subscriptionId);
|
|
187
189
|
});
|
|
188
190
|
};
|
|
189
191
|
}
|
|
@@ -203,6 +205,8 @@ export class CrdtLoroDoc<
|
|
|
203
205
|
public transact(fn: () => void): this {
|
|
204
206
|
fn();
|
|
205
207
|
|
|
208
|
+
this.value.commit();
|
|
209
|
+
|
|
206
210
|
return this;
|
|
207
211
|
}
|
|
208
212
|
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import type { AbstractCrdtType } from "@pluv/crdt";
|
|
2
1
|
import { AbstractCrdtDocFactory } from "@pluv/crdt";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { CrdtLoroObject } from "../object";
|
|
6
|
-
import { CrdtLoroText } from "../text";
|
|
2
|
+
import { LoroList, LoroMap, LoroText } from "loro-crdt";
|
|
3
|
+
import type { LoroType } from "../types";
|
|
7
4
|
import { CrdtLoroDoc } from "./CrdtLoroDoc";
|
|
8
5
|
|
|
9
6
|
export class CrdtLoroDocFactory<
|
|
10
|
-
TStorage extends Record<string,
|
|
7
|
+
TStorage extends Record<string, LoroType<any, any>>,
|
|
11
8
|
> extends AbstractCrdtDocFactory<TStorage> {
|
|
12
9
|
private _initialStorage: () => TStorage;
|
|
13
10
|
|
|
@@ -30,20 +27,16 @@ export class CrdtLoroDocFactory<
|
|
|
30
27
|
|
|
31
28
|
return new CrdtLoroDoc<TStorage>(
|
|
32
29
|
Object.entries(storage).reduce((acc, [key, node]) => {
|
|
33
|
-
if (node instanceof
|
|
34
|
-
return { ...acc, [key]: new
|
|
30
|
+
if (node instanceof LoroList) {
|
|
31
|
+
return { ...acc, [key]: new LoroList() };
|
|
35
32
|
}
|
|
36
33
|
|
|
37
|
-
if (node instanceof
|
|
38
|
-
return { ...acc, [key]: new
|
|
34
|
+
if (node instanceof LoroMap) {
|
|
35
|
+
return { ...acc, [key]: new LoroMap() };
|
|
39
36
|
}
|
|
40
37
|
|
|
41
|
-
if (node instanceof
|
|
42
|
-
return { ...acc, [key]: new
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (node instanceof CrdtLoroText) {
|
|
46
|
-
return { ...acc, [key]: new CrdtLoroText("") };
|
|
38
|
+
if (node instanceof LoroText) {
|
|
39
|
+
return { ...acc, [key]: new LoroText() };
|
|
47
40
|
}
|
|
48
41
|
|
|
49
42
|
return acc;
|
package/src/doc/doc.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { LoroType } from "../types";
|
|
2
2
|
import { CrdtLoroDocFactory } from "./CrdtLoroDocFactory";
|
|
3
3
|
|
|
4
|
-
export const doc = <TStorage extends Record<string,
|
|
4
|
+
export const doc = <TStorage extends Record<string, LoroType<any, any>>>(
|
|
5
5
|
value: () => TStorage = () => ({}) as TStorage,
|
|
6
6
|
): CrdtLoroDocFactory<TStorage> => {
|
|
7
7
|
return new CrdtLoroDocFactory<TStorage>(value);
|
package/src/list.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Container } from "loro-crdt";
|
|
2
|
+
import { LoroList, isContainer } from "loro-crdt";
|
|
3
|
+
import type { LoroType } from "./types";
|
|
4
|
+
|
|
5
|
+
export const list = <T extends unknown>(value: T[] | readonly T[] = []): LoroType<LoroList<T>, T[]> => {
|
|
6
|
+
const container = new LoroList();
|
|
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<LoroList<T>, T[]>;
|
|
13
|
+
};
|
package/src/loro.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { CrdtLoroArray, array } from "./array";
|
|
2
1
|
export { CrdtLoroDoc, doc } from "./doc";
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
6
|
-
export
|
|
2
|
+
export { list } from "./list";
|
|
3
|
+
export { map } from "./map";
|
|
4
|
+
export { object } from "./object";
|
|
5
|
+
export { text } from "./text";
|
|
6
|
+
export type { LoroType } from "./types";
|
package/src/map.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Container } from "loro-crdt";
|
|
2
|
+
import { LoroMap, isContainer } from "loro-crdt";
|
|
3
|
+
import type { LoroType } from "./types";
|
|
4
|
+
|
|
5
|
+
export const map = <T extends unknown>(
|
|
6
|
+
value: readonly (readonly [key: string, value: T])[] = [],
|
|
7
|
+
): LoroType<LoroMap<Record<string, T>>, Record<string, T>> => {
|
|
8
|
+
const container = new LoroMap();
|
|
9
|
+
|
|
10
|
+
value.forEach(([key, item]) => {
|
|
11
|
+
isContainer(item) ? container.setContainer(key, item) : container.set(key, item as Exclude<T, Container>);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
return container as unknown as LoroType<LoroMap<Record<string, T>>, Record<string, T>>;
|
|
15
|
+
};
|
package/src/object.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Container } from "loro-crdt";
|
|
2
|
+
import { LoroMap, isContainer } from "loro-crdt";
|
|
3
|
+
import type { LoroType } from "./types";
|
|
4
|
+
|
|
5
|
+
export const object = <T extends Record<string, any>>(value: T): LoroType<LoroMap<T>, T> => {
|
|
6
|
+
const container = new LoroMap();
|
|
7
|
+
|
|
8
|
+
Object.entries(value).forEach(([key, item]) => {
|
|
9
|
+
isContainer(item) ? container.setContainer(key, item) : container.set(key, item as Exclude<T, Container>);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
return container as unknown as LoroType<LoroMap<T>, T>;
|
|
13
|
+
};
|
package/src/text.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { LoroText } from "loro-crdt";
|
|
2
|
+
import type { LoroType } from "./types";
|
|
3
|
+
|
|
4
|
+
export const text = (value: string = ""): LoroType<LoroText, string> => {
|
|
5
|
+
const container = new LoroText();
|
|
6
|
+
|
|
7
|
+
container.insert(0, value);
|
|
8
|
+
|
|
9
|
+
return container as unknown as LoroType<LoroText, string>;
|
|
10
|
+
};
|
package/src/types.ts
CHANGED
|
@@ -1,40 +1,7 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { LoroList, LoroMap, LoroText } from "loro-crdt";
|
|
3
|
-
import type { CrdtLoroArray } from "./array";
|
|
4
|
-
import type { CrdtLoroMap } from "./map";
|
|
5
|
-
import type { CrdtLoroObject } from "./object";
|
|
6
|
-
import type { CrdtLoroText } from "./text";
|
|
1
|
+
import type { CrdtType } from "@pluv/crdt";
|
|
7
2
|
|
|
8
|
-
export type
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
: T extends CrdtLoroObject<infer IType>
|
|
14
|
-
? LoroMap<IType>
|
|
15
|
-
: T extends CrdtLoroText
|
|
16
|
-
? LoroText
|
|
17
|
-
: T extends Json
|
|
18
|
-
? T
|
|
19
|
-
: never;
|
|
20
|
-
|
|
21
|
-
export type InferLoroJson<T extends unknown> =
|
|
22
|
-
T extends CrdtLoroArray<infer IType>
|
|
23
|
-
? InferLoroJson<IType>[]
|
|
24
|
-
: T extends CrdtLoroMap<infer IType>
|
|
25
|
-
? Record<string, InferLoroJson<IType>>
|
|
26
|
-
: T extends CrdtLoroObject<infer IType>
|
|
27
|
-
? { [P in keyof IType]: InferLoroJson<IType[P]> }
|
|
28
|
-
: T extends CrdtLoroText | LoroText
|
|
29
|
-
? string
|
|
30
|
-
: T extends LoroList<infer IType>
|
|
31
|
-
? InferLoroJson<IType>
|
|
32
|
-
: T extends LoroMap<infer IType>
|
|
33
|
-
? { [P in keyof IType]: InferLoroJson<IType[P]> }
|
|
34
|
-
: T extends (infer IType)[]
|
|
35
|
-
? InferLoroJson<IType>[]
|
|
36
|
-
: T extends Record<any, any>
|
|
37
|
-
? { [P in keyof T]: InferLoroJson<T[P]> }
|
|
38
|
-
: T extends Json
|
|
39
|
-
? T
|
|
40
|
-
: never;
|
|
3
|
+
export type LoroType<TValue extends unknown, TJson extends unknown = any> = TValue &
|
|
4
|
+
CrdtType<TValue, TJson> & {
|
|
5
|
+
toJSON?: () => any;
|
|
6
|
+
toString?: () => string;
|
|
7
|
+
};
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { AbstractCrdtType, type InferCrdtStorageJson } from "@pluv/crdt";
|
|
2
|
-
import { LoroList } from "loro-crdt";
|
|
3
|
-
import type { CrdtLoroDoc } from "../doc/CrdtLoroDoc";
|
|
4
|
-
import { cloneType, getLoroContainerType, isWrapper } from "../shared";
|
|
5
|
-
import type { InferLoroJson } from "../types";
|
|
6
|
-
|
|
7
|
-
export class CrdtLoroArray<T extends unknown> extends AbstractCrdtType<LoroList<T[]>, InferLoroJson<T>[]> {
|
|
8
|
-
public readonly initialValue: T[] | readonly T[];
|
|
9
|
-
|
|
10
|
-
private _doc: CrdtLoroDoc<any> | null = null;
|
|
11
|
-
private _initialized: boolean = false;
|
|
12
|
-
private _value: LoroList<T[]> = new LoroList();
|
|
13
|
-
|
|
14
|
-
constructor(value: T[] | readonly T[] = []) {
|
|
15
|
-
super();
|
|
16
|
-
|
|
17
|
-
this.initialValue = value.slice();
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
public set doc(doc: CrdtLoroDoc<any>) {
|
|
21
|
-
if (this._doc) throw new Error("Cannot overwrite array doc");
|
|
22
|
-
|
|
23
|
-
this._doc = doc;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
public get length(): number {
|
|
27
|
-
return this.value.length;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
public get value(): LoroList<T[]> {
|
|
31
|
-
return this._value;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
public set value(value: LoroList<T[]>) {
|
|
35
|
-
if (this._initialized) throw new Error("Cannot re-assign array");
|
|
36
|
-
|
|
37
|
-
this._initialized = true;
|
|
38
|
-
this._value = value;
|
|
39
|
-
|
|
40
|
-
cloneType({ source: this, target: this.value });
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
public delete(index: number, length: number = 1): this {
|
|
44
|
-
this._guardInitialized();
|
|
45
|
-
|
|
46
|
-
this.value.delete(index, length);
|
|
47
|
-
this._doc?.value.commit();
|
|
48
|
-
|
|
49
|
-
return this;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
public insert(index: number, ...items: T[]): this {
|
|
53
|
-
this._guardInitialized();
|
|
54
|
-
|
|
55
|
-
items.forEach((item, i) => {
|
|
56
|
-
if (!(item instanceof AbstractCrdtType)) {
|
|
57
|
-
this.value.insert(index + i, item);
|
|
58
|
-
this._doc?.value.commit();
|
|
59
|
-
|
|
60
|
-
return this;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (!isWrapper(item)) {
|
|
64
|
-
throw new Error("This type is not yet supported");
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const containerType = getLoroContainerType(item);
|
|
68
|
-
const container = this.value.insertContainer(index + i, containerType);
|
|
69
|
-
|
|
70
|
-
cloneType({ source: item, target: container as any });
|
|
71
|
-
if (this._doc) item.doc = this._doc;
|
|
72
|
-
|
|
73
|
-
return this;
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
this._doc?.value.commit();
|
|
77
|
-
|
|
78
|
-
return this;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
public push(...items: T[]): this {
|
|
82
|
-
return this.insert(this.length, ...items);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
public unshift(...items: T[]): this {
|
|
86
|
-
return this.insert(0, ...items);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
public toJson(): InferCrdtStorageJson<InferLoroJson<T>>[] {
|
|
90
|
-
return this.value.toJson();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
private _guardInitialized(): void {
|
|
94
|
-
if (!this._initialized) throw new Error("Array is not yet initialized");
|
|
95
|
-
}
|
|
96
|
-
}
|
package/src/array/array.ts
DELETED
package/src/array/index.ts
DELETED
package/src/map/CrdtLoroMap.ts
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import type { InferCrdtStorageJson } from "@pluv/crdt";
|
|
2
|
-
import { AbstractCrdtType } from "@pluv/crdt";
|
|
3
|
-
import { LoroMap } from "loro-crdt";
|
|
4
|
-
import type { CrdtLoroDoc } from "../doc/CrdtLoroDoc";
|
|
5
|
-
import { cloneType, getLoroContainerType, isWrapper } from "../shared";
|
|
6
|
-
import type { InferLoroJson } from "../types";
|
|
7
|
-
|
|
8
|
-
export class CrdtLoroMap<T extends unknown> extends AbstractCrdtType<
|
|
9
|
-
LoroMap<Record<string, T>>,
|
|
10
|
-
Record<string, InferLoroJson<T>>
|
|
11
|
-
> {
|
|
12
|
-
public readonly initialValue: readonly (readonly [key: string, value: T])[];
|
|
13
|
-
|
|
14
|
-
private _doc: CrdtLoroDoc<any> | null = null;
|
|
15
|
-
private _initialized: boolean = false;
|
|
16
|
-
private _value: LoroMap<Record<string, T>> = new LoroMap();
|
|
17
|
-
|
|
18
|
-
constructor(value: readonly (readonly [key: string, value: T])[] = []) {
|
|
19
|
-
super();
|
|
20
|
-
|
|
21
|
-
this.initialValue = value.map(([k, v]) => [k, v] as [key: string, value: T]);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
public set doc(doc: CrdtLoroDoc<any>) {
|
|
25
|
-
if (this._doc) throw new Error("Cannot overwrite array doc");
|
|
26
|
-
|
|
27
|
-
this._doc = doc;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
public get size(): number {
|
|
31
|
-
return this.value.size;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
public get value(): LoroMap<Record<string, T>> {
|
|
35
|
-
return this._value;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
public set value(value: LoroMap<Record<string, T>>) {
|
|
39
|
-
if (this._initialized) throw new Error("Cannot re-assign map");
|
|
40
|
-
|
|
41
|
-
this._initialized = true;
|
|
42
|
-
this._value = value;
|
|
43
|
-
|
|
44
|
-
cloneType({ source: this, target: this.value });
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
public delete(prop: string): this {
|
|
48
|
-
this._guardInitialized();
|
|
49
|
-
|
|
50
|
-
this.value.delete(prop);
|
|
51
|
-
this._doc?.value.commit();
|
|
52
|
-
|
|
53
|
-
return this;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
public set(prop: string, value: T): this {
|
|
57
|
-
this._guardInitialized();
|
|
58
|
-
|
|
59
|
-
if (!(value instanceof AbstractCrdtType)) {
|
|
60
|
-
this.value.set(prop, value);
|
|
61
|
-
this._doc?.value.commit();
|
|
62
|
-
|
|
63
|
-
return this;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (!isWrapper(value)) {
|
|
67
|
-
throw new Error("This type is not yet supported");
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const containerType = getLoroContainerType(value);
|
|
71
|
-
const container = this.value.setContainer(prop, containerType);
|
|
72
|
-
|
|
73
|
-
cloneType({ source: value, target: container as any });
|
|
74
|
-
if (this._doc) value.doc = this._doc;
|
|
75
|
-
|
|
76
|
-
this._doc?.value.commit();
|
|
77
|
-
|
|
78
|
-
return this;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
public toJson(): InferCrdtStorageJson<Record<string, InferLoroJson<T>>> {
|
|
82
|
-
return this.value.toJson();
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
private _guardInitialized(): void {
|
|
86
|
-
if (!this._initialized) throw new Error("Array is not yet initialized");
|
|
87
|
-
}
|
|
88
|
-
}
|
package/src/map/index.ts
DELETED
package/src/map/map.ts
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { AbstractCrdtType, type InferCrdtStorageJson } from "@pluv/crdt";
|
|
2
|
-
import { LoroMap } from "loro-crdt";
|
|
3
|
-
import type { CrdtLoroDoc } from "../doc/CrdtLoroDoc";
|
|
4
|
-
import { cloneType, getLoroContainerType, isWrapper } from "../shared";
|
|
5
|
-
import type { InferLoroJson } from "../types";
|
|
6
|
-
|
|
7
|
-
export class CrdtLoroObject<T extends Record<string, any>> extends AbstractCrdtType<LoroMap<T>, InferLoroJson<T>> {
|
|
8
|
-
public readonly initialValue: readonly (readonly [key: string, value: T])[];
|
|
9
|
-
|
|
10
|
-
private _doc: CrdtLoroDoc<any> | null = null;
|
|
11
|
-
private _initialized: boolean = false;
|
|
12
|
-
private _value: LoroMap<T> = new LoroMap();
|
|
13
|
-
|
|
14
|
-
constructor(value: T) {
|
|
15
|
-
super();
|
|
16
|
-
|
|
17
|
-
this.initialValue = Object.entries(value).map(([k, v]) => [k, v] as [key: string, value: T]);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
public set doc(doc: CrdtLoroDoc<any>) {
|
|
21
|
-
if (this._doc) throw new Error("Cannot overwrite array doc");
|
|
22
|
-
|
|
23
|
-
this._doc = doc;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
public get size(): number {
|
|
27
|
-
return this.value.size;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
public get value(): LoroMap<T> {
|
|
31
|
-
return this._value;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
public set value(value: LoroMap<T>) {
|
|
35
|
-
if (this._initialized) throw new Error("Cannot re-assign map");
|
|
36
|
-
|
|
37
|
-
this._initialized = true;
|
|
38
|
-
this._value = value;
|
|
39
|
-
|
|
40
|
-
cloneType({ source: this, target: this.value });
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
public set(prop: string, value: T): this {
|
|
44
|
-
this._guardInitialized();
|
|
45
|
-
|
|
46
|
-
if (!(value instanceof AbstractCrdtType)) {
|
|
47
|
-
this.value.set(prop, value);
|
|
48
|
-
this._doc?.value.commit();
|
|
49
|
-
|
|
50
|
-
return this;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (!isWrapper(value)) {
|
|
54
|
-
throw new Error("This type is not yet supported");
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const containerType = getLoroContainerType(value);
|
|
58
|
-
const container = this.value.setContainer(prop, containerType);
|
|
59
|
-
|
|
60
|
-
cloneType({ source: value, target: container as any });
|
|
61
|
-
if (this._doc) value.doc = this._doc;
|
|
62
|
-
|
|
63
|
-
this._doc?.value.commit();
|
|
64
|
-
|
|
65
|
-
return this;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
public toJson(): InferCrdtStorageJson<InferLoroJson<T>> {
|
|
69
|
-
return this.value.toJson() as InferCrdtStorageJson<InferLoroJson<T>>;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
private _guardInitialized(): void {
|
|
73
|
-
if (!this._initialized) throw new Error("Array is not yet initialized");
|
|
74
|
-
}
|
|
75
|
-
}
|
package/src/object/index.ts
DELETED