@liveblocks/client 0.12.1 → 0.13.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 +34 -6
- package/lib/cjs/AbstractCrdt.d.ts +61 -0
- package/lib/cjs/AbstractCrdt.js +98 -0
- package/lib/cjs/LiveList.d.ts +133 -0
- package/lib/cjs/LiveList.js +374 -0
- package/lib/cjs/LiveMap.d.ts +83 -0
- package/lib/cjs/LiveMap.js +272 -0
- package/lib/cjs/LiveObject.d.ts +61 -0
- package/lib/cjs/LiveObject.js +330 -0
- package/lib/cjs/LiveRegister.d.ts +21 -0
- package/lib/cjs/LiveRegister.js +69 -0
- package/lib/cjs/index.d.ts +3 -1
- package/lib/cjs/index.js +7 -5
- package/lib/cjs/room.d.ts +50 -9
- package/lib/cjs/room.js +476 -85
- package/lib/cjs/types.d.ts +174 -40
- package/lib/cjs/utils.d.ts +7 -0
- package/lib/cjs/utils.js +64 -1
- package/lib/esm/AbstractCrdt.d.ts +61 -0
- package/lib/esm/AbstractCrdt.js +94 -0
- package/lib/esm/LiveList.d.ts +133 -0
- package/lib/esm/LiveList.js +370 -0
- package/lib/esm/LiveMap.d.ts +83 -0
- package/lib/esm/LiveMap.js +268 -0
- package/lib/esm/LiveObject.d.ts +61 -0
- package/lib/esm/LiveObject.js +326 -0
- package/lib/esm/LiveRegister.d.ts +21 -0
- package/lib/esm/LiveRegister.js +65 -0
- package/lib/esm/index.d.ts +3 -1
- package/lib/esm/index.js +3 -1
- package/lib/esm/room.d.ts +50 -9
- package/lib/esm/room.js +478 -84
- package/lib/esm/types.d.ts +174 -40
- package/lib/esm/utils.d.ts +7 -0
- package/lib/esm/utils.js +58 -0
- package/package.json +3 -3
- package/lib/cjs/doc.d.ts +0 -347
- package/lib/cjs/doc.js +0 -1349
- package/lib/cjs/storage.d.ts +0 -21
- package/lib/cjs/storage.js +0 -68
- package/lib/esm/doc.d.ts +0 -347
- package/lib/esm/doc.js +0 -1342
- package/lib/esm/storage.d.ts +0 -21
- package/lib/esm/storage.js +0 -65
package/README.md
CHANGED
|
@@ -1,17 +1,45 @@
|
|
|
1
1
|
<p align="center">
|
|
2
2
|
<a href="https://liveblocks.io">
|
|
3
|
-
<img src="https://liveblocks.io/
|
|
3
|
+
<img src="https://liveblocks.io/images/blog/introducing-liveblocks.png">
|
|
4
4
|
</a>
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
|
-
#
|
|
7
|
+
# Liveblocks · [](https://twitter.com/liveblocks)
|
|
8
8
|
|
|
9
|
-
Liveblocks
|
|
9
|
+
**At [Liveblocks](https://liveblocks.io), we’re building tools to help companies create world-class collaborative products that attract, engage and retain users.** This repository is a set of open-source packages for building performant and reliable multiplayer experiences.
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
npm install @liveblocks/client
|
|
15
|
+
```
|
|
12
16
|
|
|
13
17
|
## Examples
|
|
14
18
|
|
|
15
|
-
|
|
19
|
+
- Browse our gallery of collaborative UI patterns. [View examples gallery](https://liveblocks.io/examples)
|
|
20
|
+
- Explore and clone any of our open-source examples. [View code examples](https://github.com/liveblocks/liveblocks/tree/main/examples)
|
|
21
|
+
|
|
22
|
+
## Documentation
|
|
23
|
+
|
|
24
|
+
[Read the documentation](https://liveblocks.io/docs) to start using Liveblocks.
|
|
25
|
+
|
|
26
|
+
## Releases
|
|
27
|
+
|
|
28
|
+
For changelog, visit [https://github.com/liveblocks/liveblocks/releases](https://github.com/liveblocks/liveblocks/releases).
|
|
29
|
+
|
|
30
|
+
## Authors
|
|
31
|
+
|
|
32
|
+
- Guillaume Salles ([@guillaume_slls](https://twitter.com/guillaume_slls)) - [Liveblocks](https://liveblocks.io)
|
|
33
|
+
- Olivier Foucherot ([@ofoucherot](https://twitter.com/ofoucherot)) - [Liveblocks](https://liveblocks.io)
|
|
34
|
+
- Steven Fabre ([@stevenfabre](https://twitter.com/stevenfabre)) - [Liveblocks](https://liveblocks.io)
|
|
35
|
+
|
|
36
|
+
## Community
|
|
37
|
+
|
|
38
|
+
- [Discord](https://discord.gg/X4YWJuH9VY) - To get involved with the Liveblocks community, ask questions and share tips.
|
|
39
|
+
- [Twitter](https://twitter.com/liveblocks) - To receive updates, announcements, blog posts, and general Liveblocks tips.
|
|
40
|
+
|
|
41
|
+
## License
|
|
42
|
+
|
|
43
|
+
Licensed under the Apache License 2.0, Copyright © 2021-present [Liveblocks](https://liveblocks.io).
|
|
16
44
|
|
|
17
|
-
|
|
45
|
+
See [LICENSE](../../LICENSE) for more information.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Op } from "./live";
|
|
2
|
+
export declare type ApplyResult = {
|
|
3
|
+
reverse: Op[];
|
|
4
|
+
modified: AbstractCrdt;
|
|
5
|
+
} | {
|
|
6
|
+
modified: false;
|
|
7
|
+
};
|
|
8
|
+
export interface Doc {
|
|
9
|
+
generateId: () => string;
|
|
10
|
+
generateOpId: () => string;
|
|
11
|
+
addItem: (id: string, item: AbstractCrdt) => void;
|
|
12
|
+
deleteItem: (id: string) => void;
|
|
13
|
+
dispatch: (ops: Op[], reverseOps: Op[], modified: AbstractCrdt[]) => void;
|
|
14
|
+
}
|
|
15
|
+
export declare abstract class AbstractCrdt {
|
|
16
|
+
#private;
|
|
17
|
+
/**
|
|
18
|
+
* INTERNAL
|
|
19
|
+
*/
|
|
20
|
+
protected get _doc(): Doc | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* INTERNAL
|
|
23
|
+
*/
|
|
24
|
+
get _id(): string | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* INTERNAL
|
|
27
|
+
*/
|
|
28
|
+
get _parent(): AbstractCrdt | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* INTERNAL
|
|
31
|
+
*/
|
|
32
|
+
get _parentKey(): string | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* INTERNAL
|
|
35
|
+
*/
|
|
36
|
+
_apply(op: Op): ApplyResult;
|
|
37
|
+
/**
|
|
38
|
+
* INTERNAL
|
|
39
|
+
*/
|
|
40
|
+
_setParentLink(parent: AbstractCrdt, key: string): void;
|
|
41
|
+
/**
|
|
42
|
+
* INTERNAL
|
|
43
|
+
*/
|
|
44
|
+
_attach(id: string, doc: Doc): void;
|
|
45
|
+
/**
|
|
46
|
+
* INTERNAL
|
|
47
|
+
*/
|
|
48
|
+
abstract _attachChild(id: string, key: string, crdt: AbstractCrdt): ApplyResult;
|
|
49
|
+
/**
|
|
50
|
+
* INTERNAL
|
|
51
|
+
*/
|
|
52
|
+
_detach(): void;
|
|
53
|
+
/**
|
|
54
|
+
* INTERNAL
|
|
55
|
+
*/
|
|
56
|
+
abstract _detachChild(crdt: AbstractCrdt): void;
|
|
57
|
+
/**
|
|
58
|
+
* INTERNAL
|
|
59
|
+
*/
|
|
60
|
+
abstract _serialize(parentId: string, parentKey: string): Op[];
|
|
61
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
5
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
8
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
11
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
12
|
+
};
|
|
13
|
+
var _AbstractCrdt_parent, _AbstractCrdt_doc, _AbstractCrdt_id, _AbstractCrdt_parentKey;
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.AbstractCrdt = void 0;
|
|
16
|
+
const live_1 = require("./live");
|
|
17
|
+
class AbstractCrdt {
|
|
18
|
+
constructor() {
|
|
19
|
+
_AbstractCrdt_parent.set(this, void 0);
|
|
20
|
+
_AbstractCrdt_doc.set(this, void 0);
|
|
21
|
+
_AbstractCrdt_id.set(this, void 0);
|
|
22
|
+
_AbstractCrdt_parentKey.set(this, void 0);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* INTERNAL
|
|
26
|
+
*/
|
|
27
|
+
get _doc() {
|
|
28
|
+
return __classPrivateFieldGet(this, _AbstractCrdt_doc, "f");
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* INTERNAL
|
|
32
|
+
*/
|
|
33
|
+
get _id() {
|
|
34
|
+
return __classPrivateFieldGet(this, _AbstractCrdt_id, "f");
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* INTERNAL
|
|
38
|
+
*/
|
|
39
|
+
get _parent() {
|
|
40
|
+
return __classPrivateFieldGet(this, _AbstractCrdt_parent, "f");
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* INTERNAL
|
|
44
|
+
*/
|
|
45
|
+
get _parentKey() {
|
|
46
|
+
return __classPrivateFieldGet(this, _AbstractCrdt_parentKey, "f");
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* INTERNAL
|
|
50
|
+
*/
|
|
51
|
+
_apply(op) {
|
|
52
|
+
switch (op.type) {
|
|
53
|
+
case live_1.OpType.DeleteCrdt: {
|
|
54
|
+
if (this._parent != null && this._parentKey != null) {
|
|
55
|
+
const parent = this._parent;
|
|
56
|
+
const reverse = this._serialize(this._parent._id, this._parentKey);
|
|
57
|
+
this._parent._detachChild(this);
|
|
58
|
+
return { modified: parent, reverse };
|
|
59
|
+
}
|
|
60
|
+
return { modified: false };
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return { modified: false };
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* INTERNAL
|
|
67
|
+
*/
|
|
68
|
+
_setParentLink(parent, key) {
|
|
69
|
+
if (__classPrivateFieldGet(this, _AbstractCrdt_parent, "f") != null && __classPrivateFieldGet(this, _AbstractCrdt_parent, "f") !== parent) {
|
|
70
|
+
throw new Error("Cannot attach parent if it already exist");
|
|
71
|
+
}
|
|
72
|
+
__classPrivateFieldSet(this, _AbstractCrdt_parentKey, key, "f");
|
|
73
|
+
__classPrivateFieldSet(this, _AbstractCrdt_parent, parent, "f");
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* INTERNAL
|
|
77
|
+
*/
|
|
78
|
+
_attach(id, doc) {
|
|
79
|
+
if (__classPrivateFieldGet(this, _AbstractCrdt_id, "f") || __classPrivateFieldGet(this, _AbstractCrdt_doc, "f")) {
|
|
80
|
+
throw new Error("Cannot attach if CRDT is already attached");
|
|
81
|
+
}
|
|
82
|
+
doc.addItem(id, this);
|
|
83
|
+
__classPrivateFieldSet(this, _AbstractCrdt_id, id, "f");
|
|
84
|
+
__classPrivateFieldSet(this, _AbstractCrdt_doc, doc, "f");
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* INTERNAL
|
|
88
|
+
*/
|
|
89
|
+
_detach() {
|
|
90
|
+
if (__classPrivateFieldGet(this, _AbstractCrdt_doc, "f") && __classPrivateFieldGet(this, _AbstractCrdt_id, "f")) {
|
|
91
|
+
__classPrivateFieldGet(this, _AbstractCrdt_doc, "f").deleteItem(__classPrivateFieldGet(this, _AbstractCrdt_id, "f"));
|
|
92
|
+
}
|
|
93
|
+
__classPrivateFieldSet(this, _AbstractCrdt_parent, undefined, "f");
|
|
94
|
+
__classPrivateFieldSet(this, _AbstractCrdt_doc, undefined, "f");
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.AbstractCrdt = AbstractCrdt;
|
|
98
|
+
_AbstractCrdt_parent = new WeakMap(), _AbstractCrdt_doc = new WeakMap(), _AbstractCrdt_id = new WeakMap(), _AbstractCrdt_parentKey = new WeakMap();
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { AbstractCrdt, Doc, ApplyResult } from "./AbstractCrdt";
|
|
2
|
+
import { SerializedList, SerializedCrdtWithId, Op } from "./live";
|
|
3
|
+
/**
|
|
4
|
+
* The LiveList class represents an ordered collection of items that is synchorinized across clients.
|
|
5
|
+
*/
|
|
6
|
+
export declare class LiveList<T> extends AbstractCrdt {
|
|
7
|
+
#private;
|
|
8
|
+
constructor(items?: T[]);
|
|
9
|
+
/**
|
|
10
|
+
* INTERNAL
|
|
11
|
+
*/
|
|
12
|
+
static _deserialize([id, item]: [id: string, item: SerializedList], parentToChildren: Map<string, SerializedCrdtWithId[]>, doc: Doc): LiveList<never>;
|
|
13
|
+
/**
|
|
14
|
+
* INTERNAL
|
|
15
|
+
*/
|
|
16
|
+
_serialize(parentId?: string, parentKey?: string): Op[];
|
|
17
|
+
/**
|
|
18
|
+
* INTERNAL
|
|
19
|
+
*/
|
|
20
|
+
_attach(id: string, doc: Doc): void;
|
|
21
|
+
/**
|
|
22
|
+
* INTERNAL
|
|
23
|
+
*/
|
|
24
|
+
_detach(): void;
|
|
25
|
+
/**
|
|
26
|
+
* INTERNAL
|
|
27
|
+
*/
|
|
28
|
+
_attachChild(id: string, key: string, child: AbstractCrdt): ApplyResult;
|
|
29
|
+
/**
|
|
30
|
+
* INTERNAL
|
|
31
|
+
*/
|
|
32
|
+
_detachChild(child: AbstractCrdt): void;
|
|
33
|
+
/**
|
|
34
|
+
* INTERNAL
|
|
35
|
+
*/
|
|
36
|
+
_setChildKey(key: string, child: AbstractCrdt): void;
|
|
37
|
+
/**
|
|
38
|
+
* INTERNAL
|
|
39
|
+
*/
|
|
40
|
+
_apply(op: Op): ApplyResult;
|
|
41
|
+
/**
|
|
42
|
+
* Returns the number of elements.
|
|
43
|
+
*/
|
|
44
|
+
get length(): number;
|
|
45
|
+
/**
|
|
46
|
+
* Adds one element to the end of the LiveList.
|
|
47
|
+
* @param element The element to add to the end of the LiveList.
|
|
48
|
+
*/
|
|
49
|
+
push(element: T): void;
|
|
50
|
+
/**
|
|
51
|
+
* Inserts one element at a specified index.
|
|
52
|
+
* @param element The element to insert.
|
|
53
|
+
* @param index The index at which you want to insert the element.
|
|
54
|
+
*/
|
|
55
|
+
insert(element: T, index: number): void;
|
|
56
|
+
/**
|
|
57
|
+
* Move one element from one index to another.
|
|
58
|
+
* @param index The index of the element to move
|
|
59
|
+
* @param targetIndex The index where the element should be after moving.
|
|
60
|
+
*/
|
|
61
|
+
move(index: number, targetIndex: number): void;
|
|
62
|
+
/**
|
|
63
|
+
* Deletes an element at the specified index
|
|
64
|
+
* @param index The index of the element to delete
|
|
65
|
+
*/
|
|
66
|
+
delete(index: number): void;
|
|
67
|
+
/**
|
|
68
|
+
* Returns an Array of all the elements in the LiveList.
|
|
69
|
+
*/
|
|
70
|
+
toArray(): T[];
|
|
71
|
+
/**
|
|
72
|
+
* Tests whether all elements pass the test implemented by the provided function.
|
|
73
|
+
* @param predicate Function to test for each element, taking two arguments (the element and its index).
|
|
74
|
+
* @returns true if the predicate function returns a truthy value for every element. Otherwise, false.
|
|
75
|
+
*/
|
|
76
|
+
every(predicate: (value: T, index: number) => unknown): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Creates an array with all elements that pass the test implemented by the provided function.
|
|
79
|
+
* @param predicate Function to test each element of the LiveList. Return a value that coerces to true to keep the element, or to false otherwise.
|
|
80
|
+
* @returns An array with the elements that pass the test.
|
|
81
|
+
*/
|
|
82
|
+
filter(predicate: (value: T, index: number) => unknown): T[];
|
|
83
|
+
/**
|
|
84
|
+
* Returns the first element that satisfies the provided testing function.
|
|
85
|
+
* @param predicate Function to execute on each value.
|
|
86
|
+
* @returns The value of the first element in the LiveList that satisfies the provided testing function. Otherwise, undefined is returned.
|
|
87
|
+
*/
|
|
88
|
+
find(predicate: (value: T, index: number) => unknown): T | undefined;
|
|
89
|
+
/**
|
|
90
|
+
* Returns the index of the first element in the LiveList that satisfies the provided testing function.
|
|
91
|
+
* @param predicate Function to execute on each value until the function returns true, indicating that the satisfying element was found.
|
|
92
|
+
* @returns The index of the first element in the LiveList that passes the test. Otherwise, -1.
|
|
93
|
+
*/
|
|
94
|
+
findIndex(predicate: (value: T, index: number) => unknown): number;
|
|
95
|
+
/**
|
|
96
|
+
* Executes a provided function once for each element.
|
|
97
|
+
* @param callbackfn Function to execute on each element.
|
|
98
|
+
*/
|
|
99
|
+
forEach(callbackfn: (value: T, index: number) => void): void;
|
|
100
|
+
/**
|
|
101
|
+
* Get the element at the specified index.
|
|
102
|
+
* @param index The index on the element to get.
|
|
103
|
+
* @returns The element at the specified index or undefined.
|
|
104
|
+
*/
|
|
105
|
+
get(index: number): T | undefined;
|
|
106
|
+
/**
|
|
107
|
+
* Returns the first index at which a given element can be found in the LiveList, or -1 if it is not present.
|
|
108
|
+
* @param searchElement Element to locate.
|
|
109
|
+
* @param fromIndex The index to start the search at.
|
|
110
|
+
* @returns The first index of the element in the LiveList; -1 if not found.
|
|
111
|
+
*/
|
|
112
|
+
indexOf(searchElement: T, fromIndex?: number): number;
|
|
113
|
+
/**
|
|
114
|
+
* Returns the last index at which a given element can be found in the LiveList, or -1 if it is not present. The LiveLsit is searched backwards, starting at fromIndex.
|
|
115
|
+
* @param searchElement Element to locate.
|
|
116
|
+
* @param fromIndex The index at which to start searching backwards.
|
|
117
|
+
* @returns
|
|
118
|
+
*/
|
|
119
|
+
lastIndexOf(searchElement: T, fromIndex?: number): number;
|
|
120
|
+
/**
|
|
121
|
+
* Creates an array populated with the results of calling a provided function on every element.
|
|
122
|
+
* @param callback Function that is called for every element.
|
|
123
|
+
* @returns An array with each element being the result of the callback function.
|
|
124
|
+
*/
|
|
125
|
+
map<U>(callback: (value: T, index: number) => U): U[];
|
|
126
|
+
/**
|
|
127
|
+
* Tests whether at least one element in the LiveList passes the test implemented by the provided function.
|
|
128
|
+
* @param predicate Function to test for each element.
|
|
129
|
+
* @returns true if the callback function returns a truthy value for at least one element. Otherwise, false.
|
|
130
|
+
*/
|
|
131
|
+
some(predicate: (value: T, index: number) => unknown): boolean;
|
|
132
|
+
[Symbol.iterator](): IterableIterator<T>;
|
|
133
|
+
}
|