@liveblocks/client 0.17.0-beta1 → 0.17.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 +18 -9
- package/index.js +3 -1
- package/index.mjs +2 -1
- package/internal.d.ts +8 -8
- package/package.json +1 -1
- package/shared.d.ts +13 -13
- package/shared.js +25 -11
- package/shared.mjs +21 -11
package/README.md
CHANGED
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
</a>
|
|
19
19
|
</p>
|
|
20
20
|
|
|
21
|
-
A client that lets you interact with [Liveblocks](https://liveblocks.io)
|
|
21
|
+
A client that lets you interact with [Liveblocks](https://liveblocks.io)
|
|
22
|
+
servers.
|
|
22
23
|
|
|
23
24
|
## Installation
|
|
24
25
|
|
|
@@ -28,25 +29,33 @@ npm install @liveblocks/client
|
|
|
28
29
|
|
|
29
30
|
## Documentation
|
|
30
31
|
|
|
31
|
-
- [Read the documentation](https://liveblocks.io/docs) to start using
|
|
32
|
-
|
|
32
|
+
- [Read the documentation](https://liveblocks.io/docs) to start using
|
|
33
|
+
Liveblocks.
|
|
34
|
+
- Explore the
|
|
35
|
+
[API Reference](https://liveblocks.io/docs/api-reference/liveblocks-client).
|
|
33
36
|
|
|
34
37
|
## Examples
|
|
35
38
|
|
|
36
|
-
- Browse our gallery of collaborative UI patterns.
|
|
37
|
-
|
|
39
|
+
- Browse our gallery of collaborative UI patterns.
|
|
40
|
+
[View examples gallery](https://liveblocks.io/examples)
|
|
41
|
+
- Explore and clone any of our open-source examples.
|
|
42
|
+
[View code examples](https://github.com/liveblocks/liveblocks/tree/main/examples)
|
|
38
43
|
|
|
39
44
|
## Releases
|
|
40
45
|
|
|
41
|
-
For changelog, visit
|
|
46
|
+
For changelog, visit
|
|
47
|
+
[https://github.com/liveblocks/liveblocks/releases](https://github.com/liveblocks/liveblocks/releases).
|
|
42
48
|
|
|
43
49
|
## Community
|
|
44
50
|
|
|
45
|
-
- [Discord](https://discord.gg/X4YWJuH9VY) - To get involved with the Liveblocks
|
|
46
|
-
|
|
51
|
+
- [Discord](https://discord.gg/X4YWJuH9VY) - To get involved with the Liveblocks
|
|
52
|
+
community, ask questions and share tips.
|
|
53
|
+
- [Twitter](https://twitter.com/liveblocks) - To receive updates, announcements,
|
|
54
|
+
blog posts, and general Liveblocks tips.
|
|
47
55
|
|
|
48
56
|
## License
|
|
49
57
|
|
|
50
|
-
Licensed under the Apache License 2.0, Copyright © 2021-present
|
|
58
|
+
Licensed under the Apache License 2.0, Copyright © 2021-present
|
|
59
|
+
[Liveblocks](https://liveblocks.io).
|
|
51
60
|
|
|
52
61
|
See [LICENSE](../../LICENSE) for more information.
|
package/index.js
CHANGED
|
@@ -413,7 +413,9 @@ function makeStateMachine(state, context, mockedEffects) {
|
|
|
413
413
|
);
|
|
414
414
|
var ws = WebSocketPolyfill || WebSocket;
|
|
415
415
|
return function (token) {
|
|
416
|
-
return new ws(
|
|
416
|
+
return new ws(
|
|
417
|
+
liveblocksServer + "/?token=" + token + "&version=0.17.0"
|
|
418
|
+
);
|
|
417
419
|
};
|
|
418
420
|
})(
|
|
419
421
|
context.liveblocksServer,
|
package/index.mjs
CHANGED
|
@@ -336,7 +336,8 @@ function makeStateMachine(state, context, mockedEffects) {
|
|
|
336
336
|
"To use Liveblocks client in a non-dom environment, you need to provide a WebSocket polyfill."
|
|
337
337
|
);
|
|
338
338
|
const ws = WebSocketPolyfill || WebSocket;
|
|
339
|
-
return (token) =>
|
|
339
|
+
return (token) =>
|
|
340
|
+
new ws(`${liveblocksServer}/?token=${token}&version=0.17.0`);
|
|
340
341
|
})(
|
|
341
342
|
context.liveblocksServer,
|
|
342
343
|
null !==
|
package/internal.d.ts
CHANGED
|
@@ -123,14 +123,14 @@ declare enum ClientMsgCode {
|
|
|
123
123
|
/**
|
|
124
124
|
* Messages that can be sent from the client to the server.
|
|
125
125
|
*/
|
|
126
|
-
declare type ClientMsg<TPresence extends JsonObject,
|
|
127
|
-
| BroadcastEventClientMsg<
|
|
126
|
+
declare type ClientMsg<TPresence extends JsonObject, TRoomEvent extends Json> =
|
|
127
|
+
| BroadcastEventClientMsg<TRoomEvent>
|
|
128
128
|
| UpdatePresenceClientMsg<TPresence>
|
|
129
129
|
| UpdateStorageClientMsg
|
|
130
130
|
| FetchStorageClientMsg;
|
|
131
|
-
declare type BroadcastEventClientMsg<
|
|
131
|
+
declare type BroadcastEventClientMsg<TRoomEvent extends Json> = {
|
|
132
132
|
type: ClientMsgCode.BROADCAST_EVENT;
|
|
133
|
-
event:
|
|
133
|
+
event: TRoomEvent;
|
|
134
134
|
};
|
|
135
135
|
declare type UpdatePresenceClientMsg<TPresence extends JsonObject> = {
|
|
136
136
|
type: ClientMsgCode.UPDATE_PRESENCE;
|
|
@@ -220,12 +220,12 @@ declare enum ServerMsgCode {
|
|
|
220
220
|
declare type ServerMsg<
|
|
221
221
|
TPresence extends JsonObject,
|
|
222
222
|
TUserMeta extends BaseUserMeta,
|
|
223
|
-
|
|
223
|
+
TRoomEvent extends Json
|
|
224
224
|
> =
|
|
225
225
|
| UpdatePresenceServerMsg<TPresence>
|
|
226
226
|
| UserJoinServerMsg<TUserMeta>
|
|
227
227
|
| UserLeftServerMsg
|
|
228
|
-
| BroadcastedEventServerMsg<
|
|
228
|
+
| BroadcastedEventServerMsg<TRoomEvent>
|
|
229
229
|
| RoomStateServerMsg<TUserMeta>
|
|
230
230
|
| InitialDocumentStateServerMsg
|
|
231
231
|
| UpdateStorageServerMsg;
|
|
@@ -289,7 +289,7 @@ declare type UserLeftServerMsg = {
|
|
|
289
289
|
* Sent by the WebSocket server and broadcasted to all clients to announce that
|
|
290
290
|
* a User broadcasted an Event to everyone in the Room.
|
|
291
291
|
*/
|
|
292
|
-
declare type BroadcastedEventServerMsg<
|
|
292
|
+
declare type BroadcastedEventServerMsg<TRoomEvent extends Json> = {
|
|
293
293
|
type: ServerMsgCode.BROADCASTED_EVENT;
|
|
294
294
|
/**
|
|
295
295
|
* The User who broadcasted the Event.
|
|
@@ -299,7 +299,7 @@ declare type BroadcastedEventServerMsg<TEvent extends Json> = {
|
|
|
299
299
|
* The arbitrary payload of the Event. This can be any JSON value. Clients
|
|
300
300
|
* will have to manually verify/decode this event.
|
|
301
301
|
*/
|
|
302
|
-
event:
|
|
302
|
+
event: TRoomEvent;
|
|
303
303
|
};
|
|
304
304
|
/**
|
|
305
305
|
* Sent by the WebSocket server to a single client in response to the client
|
package/package.json
CHANGED
package/shared.d.ts
CHANGED
|
@@ -303,12 +303,12 @@ declare type OthersEventCallback<
|
|
|
303
303
|
others: Others<TPresence, TUserMeta>,
|
|
304
304
|
event: OthersEvent<TPresence, TUserMeta>
|
|
305
305
|
) => void;
|
|
306
|
-
declare type EventCallback<
|
|
306
|
+
declare type EventCallback<TRoomEvent extends Json> = ({
|
|
307
307
|
connectionId,
|
|
308
308
|
event,
|
|
309
309
|
}: {
|
|
310
310
|
connectionId: number;
|
|
311
|
-
event:
|
|
311
|
+
event: TRoomEvent;
|
|
312
312
|
}) => void;
|
|
313
313
|
declare type ErrorCallback = (error: Error) => void;
|
|
314
314
|
declare type ConnectionCallback = (state: ConnectionState) => void;
|
|
@@ -426,12 +426,12 @@ declare type Client = {
|
|
|
426
426
|
*/
|
|
427
427
|
getRoom<
|
|
428
428
|
TPresence extends JsonObject,
|
|
429
|
-
TStorage extends LsonObject,
|
|
430
|
-
TUserMeta extends BaseUserMeta,
|
|
431
|
-
|
|
429
|
+
TStorage extends LsonObject = LsonObject,
|
|
430
|
+
TUserMeta extends BaseUserMeta = BaseUserMeta,
|
|
431
|
+
TRoomEvent extends Json = never
|
|
432
432
|
>(
|
|
433
433
|
roomId: string
|
|
434
|
-
): Room<TPresence, TStorage, TUserMeta,
|
|
434
|
+
): Room<TPresence, TStorage, TUserMeta, TRoomEvent> | null;
|
|
435
435
|
/**
|
|
436
436
|
* Enters a room and returns it.
|
|
437
437
|
* @param roomId The id of the room
|
|
@@ -439,13 +439,13 @@ declare type Client = {
|
|
|
439
439
|
*/
|
|
440
440
|
enter<
|
|
441
441
|
TPresence extends JsonObject,
|
|
442
|
-
TStorage extends LsonObject,
|
|
443
|
-
TUserMeta extends BaseUserMeta,
|
|
444
|
-
|
|
442
|
+
TStorage extends LsonObject = LsonObject,
|
|
443
|
+
TUserMeta extends BaseUserMeta = BaseUserMeta,
|
|
444
|
+
TRoomEvent extends Json = never
|
|
445
445
|
>(
|
|
446
446
|
roomId: string,
|
|
447
447
|
options?: RoomInitializers<TPresence, TStorage>
|
|
448
|
-
): Room<TPresence, TStorage, TUserMeta,
|
|
448
|
+
): Room<TPresence, TStorage, TUserMeta, TRoomEvent>;
|
|
449
449
|
/**
|
|
450
450
|
* Leaves a room.
|
|
451
451
|
* @param roomId The id of the room
|
|
@@ -635,7 +635,7 @@ declare type Room<
|
|
|
635
635
|
TPresence extends JsonObject,
|
|
636
636
|
TStorage extends LsonObject,
|
|
637
637
|
TUserMeta extends BaseUserMeta,
|
|
638
|
-
|
|
638
|
+
TRoomEvent extends Json
|
|
639
639
|
> = {
|
|
640
640
|
/**
|
|
641
641
|
* The id of the room.
|
|
@@ -678,7 +678,7 @@ declare type Room<
|
|
|
678
678
|
* // Do something
|
|
679
679
|
* });
|
|
680
680
|
*/
|
|
681
|
-
(type: "event", listener: EventCallback<
|
|
681
|
+
(type: "event", listener: EventCallback<TRoomEvent>): () => void;
|
|
682
682
|
/**
|
|
683
683
|
* Subscribe to errors thrown in the room.
|
|
684
684
|
*/
|
|
@@ -789,7 +789,7 @@ declare type Room<
|
|
|
789
789
|
* }
|
|
790
790
|
* });
|
|
791
791
|
*/
|
|
792
|
-
broadcastEvent: (event:
|
|
792
|
+
broadcastEvent: (event: TRoomEvent, options?: BroadcastOptions) => void;
|
|
793
793
|
/**
|
|
794
794
|
* Get the room's storage asynchronously.
|
|
795
795
|
* The storage's root is a {@link LiveObject}.
|
package/shared.js
CHANGED
|
@@ -945,14 +945,14 @@ var LiveList = (function (_AbstractCrdt) {
|
|
|
945
945
|
var parentKey = nn(child._parentKey),
|
|
946
946
|
reverse = child._serialize(nn(this._id), parentKey, this._doc),
|
|
947
947
|
indexToDelete = this._items.indexOf(child);
|
|
948
|
-
return
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
948
|
+
return -1 === indexToDelete
|
|
949
|
+
? { modified: !1 }
|
|
950
|
+
: (this._items.splice(indexToDelete, 1),
|
|
951
|
+
child._detach(),
|
|
952
|
+
{
|
|
953
|
+
modified: makeUpdate(this, [deleteDelta(indexToDelete)]),
|
|
954
|
+
reverse: reverse,
|
|
955
|
+
});
|
|
956
956
|
}
|
|
957
957
|
return { modified: !1 };
|
|
958
958
|
}),
|
|
@@ -1448,10 +1448,12 @@ var LiveMap = (function (_AbstractCrdt) {
|
|
|
1448
1448
|
var _this;
|
|
1449
1449
|
if (
|
|
1450
1450
|
(((_this = _AbstractCrdt.call(this) || this)._map = void 0),
|
|
1451
|
+
(_this.unacknowledgedSet = void 0),
|
|
1451
1452
|
errorIf(
|
|
1452
1453
|
null === entries,
|
|
1453
1454
|
"Support for calling `new LiveMap(null)` will be removed in @liveblocks/client 0.18. Please call as `new LiveMap()`, or `new LiveMap([])`."
|
|
1454
1455
|
),
|
|
1456
|
+
(_this.unacknowledgedSet = new Map()),
|
|
1455
1457
|
entries)
|
|
1456
1458
|
) {
|
|
1457
1459
|
for (
|
|
@@ -1531,14 +1533,24 @@ var LiveMap = (function (_AbstractCrdt) {
|
|
|
1531
1533
|
isLiveNode(_value3) && _value3._attach(doc.generateId(), doc);
|
|
1532
1534
|
}
|
|
1533
1535
|
}),
|
|
1534
|
-
(_proto._attachChild = function (op) {
|
|
1536
|
+
(_proto._attachChild = function (op, source) {
|
|
1535
1537
|
var _updates;
|
|
1536
1538
|
if (null == this._doc)
|
|
1537
1539
|
throw new Error("Can't attach child if doc is not present");
|
|
1538
1540
|
var id = op.id,
|
|
1539
|
-
|
|
1541
|
+
parentKey = op.parentKey,
|
|
1542
|
+
opId = op.opId,
|
|
1543
|
+
key = parentKey,
|
|
1540
1544
|
child = creationOpToLiveNode(op);
|
|
1541
1545
|
if (void 0 !== this._doc.getItem(id)) return { modified: !1 };
|
|
1546
|
+
if (source === exports.OpSource.ACK) {
|
|
1547
|
+
var lastUpdateOpId = this.unacknowledgedSet.get(key);
|
|
1548
|
+
if (lastUpdateOpId === opId)
|
|
1549
|
+
return this.unacknowledgedSet.delete(key), { modified: !1 };
|
|
1550
|
+
if (null != lastUpdateOpId) return { modified: !1 };
|
|
1551
|
+
} else
|
|
1552
|
+
source === exports.OpSource.REMOTE &&
|
|
1553
|
+
this.unacknowledgedSet.delete(key);
|
|
1542
1554
|
var reverse,
|
|
1543
1555
|
previousValue = this._map.get(key);
|
|
1544
1556
|
if (previousValue) {
|
|
@@ -1637,7 +1649,9 @@ var LiveMap = (function (_AbstractCrdt) {
|
|
|
1637
1649
|
((_updates3 = {}),
|
|
1638
1650
|
(_updates3[key] = { type: "update" }),
|
|
1639
1651
|
_updates3),
|
|
1640
|
-
})
|
|
1652
|
+
});
|
|
1653
|
+
var ops = item._serialize(this._id, key, this._doc);
|
|
1654
|
+
this.unacknowledgedSet.set(key, nn(ops[0].opId)),
|
|
1641
1655
|
this._doc.dispatch(
|
|
1642
1656
|
item._serialize(this._id, key, this._doc),
|
|
1643
1657
|
oldValue
|
package/shared.mjs
CHANGED
|
@@ -693,14 +693,14 @@ class LiveList extends AbstractCrdt {
|
|
|
693
693
|
const parentKey = nn(child._parentKey),
|
|
694
694
|
reverse = child._serialize(nn(this._id), parentKey, this._doc),
|
|
695
695
|
indexToDelete = this._items.indexOf(child);
|
|
696
|
-
return
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
696
|
+
return -1 === indexToDelete
|
|
697
|
+
? { modified: !1 }
|
|
698
|
+
: (this._items.splice(indexToDelete, 1),
|
|
699
|
+
child._detach(),
|
|
700
|
+
{
|
|
701
|
+
modified: makeUpdate(this, [deleteDelta(indexToDelete)]),
|
|
702
|
+
reverse: reverse,
|
|
703
|
+
});
|
|
704
704
|
}
|
|
705
705
|
return { modified: !1 };
|
|
706
706
|
}
|
|
@@ -1152,6 +1152,7 @@ class LiveMap extends AbstractCrdt {
|
|
|
1152
1152
|
null === entries,
|
|
1153
1153
|
"Support for calling `new LiveMap(null)` will be removed in @liveblocks/client 0.18. Please call as `new LiveMap()`, or `new LiveMap([])`."
|
|
1154
1154
|
),
|
|
1155
|
+
(this.unacknowledgedSet = new Map()),
|
|
1155
1156
|
entries)
|
|
1156
1157
|
) {
|
|
1157
1158
|
const mappedEntries = [];
|
|
@@ -1196,12 +1197,19 @@ class LiveMap extends AbstractCrdt {
|
|
|
1196
1197
|
for (const [_key, value] of this._map)
|
|
1197
1198
|
isLiveNode(value) && value._attach(doc.generateId(), doc);
|
|
1198
1199
|
}
|
|
1199
|
-
_attachChild(op) {
|
|
1200
|
+
_attachChild(op, source) {
|
|
1200
1201
|
if (null == this._doc)
|
|
1201
1202
|
throw new Error("Can't attach child if doc is not present");
|
|
1202
|
-
const { id: id, parentKey:
|
|
1203
|
+
const { id: id, parentKey: parentKey, opId: opId } = op,
|
|
1204
|
+
key = parentKey,
|
|
1203
1205
|
child = creationOpToLiveNode(op);
|
|
1204
1206
|
if (void 0 !== this._doc.getItem(id)) return { modified: !1 };
|
|
1207
|
+
if (source === OpSource.ACK) {
|
|
1208
|
+
const lastUpdateOpId = this.unacknowledgedSet.get(key);
|
|
1209
|
+
if (lastUpdateOpId === opId)
|
|
1210
|
+
return this.unacknowledgedSet.delete(key), { modified: !1 };
|
|
1211
|
+
if (null != lastUpdateOpId) return { modified: !1 };
|
|
1212
|
+
} else source === OpSource.REMOTE && this.unacknowledgedSet.delete(key);
|
|
1205
1213
|
const previousValue = this._map.get(key);
|
|
1206
1214
|
let reverse;
|
|
1207
1215
|
if (previousValue) {
|
|
@@ -1272,7 +1280,9 @@ class LiveMap extends AbstractCrdt {
|
|
|
1272
1280
|
node: this,
|
|
1273
1281
|
type: "LiveMap",
|
|
1274
1282
|
updates: { [key]: { type: "update" } },
|
|
1275
|
-
})
|
|
1283
|
+
});
|
|
1284
|
+
const ops = item._serialize(this._id, key, this._doc);
|
|
1285
|
+
this.unacknowledgedSet.set(key, nn(ops[0].opId)),
|
|
1276
1286
|
this._doc.dispatch(
|
|
1277
1287
|
item._serialize(this._id, key, this._doc),
|
|
1278
1288
|
oldValue
|