@liveblocks/core 1.1.0-test1 → 1.1.0-yjs1
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.d.ts +125 -37
- package/dist/index.js +324 -193
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -636,14 +636,34 @@ declare enum WebsocketCloseCodes {
|
|
|
636
636
|
CLOSE_WITHOUT_RETRY = 4999
|
|
637
637
|
}
|
|
638
638
|
|
|
639
|
+
/**
|
|
640
|
+
* Old connection statuses, here for backward-compatibility reasons only.
|
|
641
|
+
*/
|
|
642
|
+
declare type LegacyConnectionStatus = "closed" | "authenticating" | "connecting" | "open" | "unavailable" | "failed";
|
|
643
|
+
/**
|
|
644
|
+
* Returns a human-readable status indicating the current connection status of
|
|
645
|
+
* a Room, as returned by `room.getStatus()`. Can be used to implement
|
|
646
|
+
* a connection status badge.
|
|
647
|
+
*/
|
|
648
|
+
declare type Status = "initial" | "connecting" | "connected" | "reconnecting" | "disconnected";
|
|
649
|
+
/**
|
|
650
|
+
* Used to report about app-level reconnection issues.
|
|
651
|
+
*
|
|
652
|
+
* Normal (quick) reconnects won't be reported as a "lost connection". Instead,
|
|
653
|
+
* the application will only get an event if the reconnection attempts by the
|
|
654
|
+
* client are taking (much) longer than usual. Definitely a situation you want
|
|
655
|
+
* to inform your users about, for example, by throwing a toast message on
|
|
656
|
+
* screen, or show a "trying to reconnect" banner.
|
|
657
|
+
*/
|
|
658
|
+
declare type LostConnectionEvent = "lost" | "restored" | "failed";
|
|
639
659
|
/**
|
|
640
660
|
* Arbitrary record that will be used as the authentication "token". It's the
|
|
641
661
|
* value that is returned by calling the authentication delegate, and will get
|
|
642
662
|
* passed to the connection factory delegate. This value will be remembered by
|
|
643
663
|
* the connection manager, but its value will not be interpreted, so it can be
|
|
644
|
-
* any
|
|
664
|
+
* any value (except null).
|
|
645
665
|
*/
|
|
646
|
-
declare type BaseAuthResult =
|
|
666
|
+
declare type BaseAuthResult = NonNullable<Json>;
|
|
647
667
|
declare type Delegates<T extends BaseAuthResult> = {
|
|
648
668
|
authenticate: () => Promise<T>;
|
|
649
669
|
createSocket: (token: T) => IWebSocketInstance;
|
|
@@ -735,28 +755,6 @@ declare type CustomEvent<TRoomEvent extends Json> = {
|
|
|
735
755
|
connectionId: number;
|
|
736
756
|
event: TRoomEvent;
|
|
737
757
|
};
|
|
738
|
-
declare type Connection = {
|
|
739
|
-
status: "closed";
|
|
740
|
-
} | {
|
|
741
|
-
status: "authenticating";
|
|
742
|
-
} | {
|
|
743
|
-
status: "connecting";
|
|
744
|
-
id: number;
|
|
745
|
-
userId?: string;
|
|
746
|
-
userInfo?: Json;
|
|
747
|
-
isReadOnly: boolean;
|
|
748
|
-
} | {
|
|
749
|
-
status: "open";
|
|
750
|
-
id: number;
|
|
751
|
-
userId?: string;
|
|
752
|
-
userInfo?: Json;
|
|
753
|
-
isReadOnly: boolean;
|
|
754
|
-
} | {
|
|
755
|
-
status: "unavailable";
|
|
756
|
-
} | {
|
|
757
|
-
status: "failed";
|
|
758
|
-
};
|
|
759
|
-
declare type ConnectionStatus = Connection["status"];
|
|
760
758
|
declare type StorageStatus = "not-loaded" | "loading" | "synchronizing" | "synchronized";
|
|
761
759
|
interface History {
|
|
762
760
|
/**
|
|
@@ -893,12 +891,47 @@ declare type SubscribeFn<TPresence extends JsonObject, _TStorage extends LsonObj
|
|
|
893
891
|
*/
|
|
894
892
|
(type: "error", listener: ErrorCallback): () => void;
|
|
895
893
|
/**
|
|
896
|
-
*
|
|
894
|
+
* @deprecated This API will be removed in a future version of Liveblocks.
|
|
895
|
+
* Prefer using the newer `.subscribe('status')` API.
|
|
896
|
+
*
|
|
897
|
+
* We recommend making the following changes if you use these APIs:
|
|
898
|
+
*
|
|
899
|
+
* OLD APIs NEW APIs
|
|
900
|
+
* .getConnectionState() --> .getStatus()
|
|
901
|
+
* .subscribe('connection') --> .subscribe('status')
|
|
902
|
+
*
|
|
903
|
+
* OLD STATUSES NEW STATUSES
|
|
904
|
+
* closed --> initial
|
|
905
|
+
* authenticating --> connecting
|
|
906
|
+
* connecting --> connecting
|
|
907
|
+
* open --> connected
|
|
908
|
+
* unavailable --> reconnecting
|
|
909
|
+
* failed --> disconnected
|
|
910
|
+
*
|
|
911
|
+
* Subscribe to legacy connection status updates.
|
|
912
|
+
*
|
|
913
|
+
* @returns Unsubscribe function.
|
|
914
|
+
*
|
|
915
|
+
*/
|
|
916
|
+
(type: "connection", listener: Callback<LegacyConnectionStatus>): () => void;
|
|
917
|
+
/**
|
|
918
|
+
* Subscribe to connection status updates. The callback will be called any
|
|
919
|
+
* time the status changes.
|
|
897
920
|
*
|
|
898
921
|
* @returns Unsubscribe function.
|
|
899
922
|
*
|
|
900
923
|
*/
|
|
901
|
-
(type: "
|
|
924
|
+
(type: "status", listener: Callback<Status>): () => void;
|
|
925
|
+
/**
|
|
926
|
+
* Subscribe to the exceptional event where reconnecting to the Liveblocks
|
|
927
|
+
* servers is taking longer than usual. This typically is a sign of a client
|
|
928
|
+
* that has lost internet connectivity.
|
|
929
|
+
*
|
|
930
|
+
* This isn't problematic (because the Liveblocks client is still trying to
|
|
931
|
+
* reconnect), but it's typically a good idea to inform users about it if
|
|
932
|
+
* the connection takes too long to recover.
|
|
933
|
+
*/
|
|
934
|
+
(type: "lost-connection", listener: Callback<LostConnectionEvent>): () => void;
|
|
902
935
|
/**
|
|
903
936
|
* Subscribes to changes made on a Live structure. Returns an unsubscribe function.
|
|
904
937
|
* In a future version, we will also expose what exactly changed in the Live structure.
|
|
@@ -975,7 +1008,30 @@ declare type Room<TPresence extends JsonObject, TStorage extends LsonObject, TUs
|
|
|
975
1008
|
* metadata and connection ID (from the auth server).
|
|
976
1009
|
*/
|
|
977
1010
|
isSelfAware(): boolean;
|
|
978
|
-
|
|
1011
|
+
/**
|
|
1012
|
+
* @deprecated This API will be removed in a future version of Liveblocks.
|
|
1013
|
+
* Prefer using `.getStatus()` instead.
|
|
1014
|
+
*
|
|
1015
|
+
* We recommend making the following changes if you use these APIs:
|
|
1016
|
+
*
|
|
1017
|
+
* OLD APIs NEW APIs
|
|
1018
|
+
* .getConnectionState() --> .getStatus()
|
|
1019
|
+
* .subscribe('connection') --> .subscribe('status')
|
|
1020
|
+
*
|
|
1021
|
+
* OLD STATUSES NEW STATUSES
|
|
1022
|
+
* closed --> initial
|
|
1023
|
+
* authenticating --> connecting
|
|
1024
|
+
* connecting --> connecting
|
|
1025
|
+
* open --> connected
|
|
1026
|
+
* unavailable --> reconnecting
|
|
1027
|
+
* failed --> disconnected
|
|
1028
|
+
*/
|
|
1029
|
+
getConnectionState(): LegacyConnectionStatus;
|
|
1030
|
+
/**
|
|
1031
|
+
* Return the current connection status for this room. Can be used to display
|
|
1032
|
+
* a status badge for your Liveblocks connection.
|
|
1033
|
+
*/
|
|
1034
|
+
getStatus(): Status;
|
|
979
1035
|
readonly subscribe: SubscribeFn<TPresence, TStorage, TUserMeta, TRoomEvent>;
|
|
980
1036
|
/**
|
|
981
1037
|
* Room's history contains functions that let you undo and redo operation made on by the current client on the presence and storage.
|
|
@@ -1021,6 +1077,17 @@ declare type Room<TPresence extends JsonObject, TStorage extends LsonObject, TUs
|
|
|
1021
1077
|
*/
|
|
1022
1078
|
addToHistory: boolean;
|
|
1023
1079
|
}): void;
|
|
1080
|
+
/**
|
|
1081
|
+
*
|
|
1082
|
+
* Sends YJS document updates to liveblocks server
|
|
1083
|
+
*
|
|
1084
|
+
* @param {string} data the doc update to send to the server, base64 encoded uint8array
|
|
1085
|
+
*/
|
|
1086
|
+
updateDoc(data: string): void;
|
|
1087
|
+
/**
|
|
1088
|
+
* Sends a request for the current document from liveblocks server
|
|
1089
|
+
*/
|
|
1090
|
+
getDoc(stateVector?: string): void;
|
|
1024
1091
|
/**
|
|
1025
1092
|
* Broadcasts an event to other users in the room. Event broadcasted to the room can be listened with {@link Room.subscribe}("event").
|
|
1026
1093
|
* @param {any} event the event to broadcast. Should be serializable to JSON
|
|
@@ -1056,6 +1123,9 @@ declare type Room<TPresence extends JsonObject, TStorage extends LsonObject, TUs
|
|
|
1056
1123
|
*/
|
|
1057
1124
|
getStorageSnapshot(): LiveObject<TStorage> | null;
|
|
1058
1125
|
readonly events: {
|
|
1126
|
+
readonly connection: Observable<LegacyConnectionStatus>;
|
|
1127
|
+
readonly status: Observable<Status>;
|
|
1128
|
+
readonly lostConnection: Observable<LostConnectionEvent>;
|
|
1059
1129
|
readonly customEvent: Observable<{
|
|
1060
1130
|
connectionId: number;
|
|
1061
1131
|
event: TRoomEvent;
|
|
@@ -1066,15 +1136,16 @@ declare type Room<TPresence extends JsonObject, TStorage extends LsonObject, TUs
|
|
|
1066
1136
|
event: OthersEvent<TPresence, TUserMeta>;
|
|
1067
1137
|
}>;
|
|
1068
1138
|
readonly error: Observable<Error>;
|
|
1069
|
-
readonly connection: Observable<ConnectionStatus>;
|
|
1070
1139
|
readonly storage: Observable<StorageUpdate[]>;
|
|
1071
1140
|
readonly history: Observable<HistoryEvent>;
|
|
1072
1141
|
/**
|
|
1073
|
-
* Subscribe to the storage loaded event. Will fire
|
|
1074
|
-
*
|
|
1142
|
+
* Subscribe to the storage loaded event. Will fire any time a full Storage
|
|
1143
|
+
* copy is downloaded. (This happens after the initial connect, and on
|
|
1144
|
+
* every reconnect.)
|
|
1075
1145
|
*/
|
|
1076
1146
|
readonly storageDidLoad: Observable<void>;
|
|
1077
1147
|
readonly storageStatus: Observable<StorageStatus>;
|
|
1148
|
+
readonly docUpdated: Observable<string[]>;
|
|
1078
1149
|
};
|
|
1079
1150
|
/**
|
|
1080
1151
|
* Batches modifications made during the given function.
|
|
@@ -1168,6 +1239,7 @@ declare type AuthEndpoint = string | ((room: string) => Promise<{
|
|
|
1168
1239
|
*/
|
|
1169
1240
|
declare type ClientOptions = {
|
|
1170
1241
|
throttle?: number;
|
|
1242
|
+
lostConnectionTimeout?: number;
|
|
1171
1243
|
polyfills?: Polyfills;
|
|
1172
1244
|
unstable_fallbackToHTTP?: boolean;
|
|
1173
1245
|
/**
|
|
@@ -1396,12 +1468,14 @@ declare enum ClientMsgCode {
|
|
|
1396
1468
|
UPDATE_PRESENCE = 100,
|
|
1397
1469
|
BROADCAST_EVENT = 103,
|
|
1398
1470
|
FETCH_STORAGE = 200,
|
|
1399
|
-
UPDATE_STORAGE = 201
|
|
1471
|
+
UPDATE_STORAGE = 201,
|
|
1472
|
+
FETCH_DOC = 300,
|
|
1473
|
+
UPDATE_DOC = 301
|
|
1400
1474
|
}
|
|
1401
1475
|
/**
|
|
1402
1476
|
* Messages that can be sent from the client to the server.
|
|
1403
1477
|
*/
|
|
1404
|
-
declare type ClientMsg<TPresence extends JsonObject, TRoomEvent extends Json> = BroadcastEventClientMsg<TRoomEvent> | UpdatePresenceClientMsg<TPresence> | UpdateStorageClientMsg | FetchStorageClientMsg;
|
|
1478
|
+
declare type ClientMsg<TPresence extends JsonObject, TRoomEvent extends Json> = BroadcastEventClientMsg<TRoomEvent> | UpdatePresenceClientMsg<TPresence> | UpdateStorageClientMsg | FetchStorageClientMsg | FetchDocClientMsg | UpdateDocClientMsg;
|
|
1405
1479
|
declare type BroadcastEventClientMsg<TRoomEvent extends Json> = {
|
|
1406
1480
|
type: ClientMsgCode.BROADCAST_EVENT;
|
|
1407
1481
|
event: TRoomEvent;
|
|
@@ -1439,6 +1513,14 @@ declare type UpdateStorageClientMsg = {
|
|
|
1439
1513
|
declare type FetchStorageClientMsg = {
|
|
1440
1514
|
readonly type: ClientMsgCode.FETCH_STORAGE;
|
|
1441
1515
|
};
|
|
1516
|
+
declare type FetchDocClientMsg = {
|
|
1517
|
+
readonly type: ClientMsgCode.FETCH_DOC;
|
|
1518
|
+
readonly vector?: string;
|
|
1519
|
+
};
|
|
1520
|
+
declare type UpdateDocClientMsg = {
|
|
1521
|
+
readonly type: ClientMsgCode.UPDATE_DOC;
|
|
1522
|
+
readonly data: string;
|
|
1523
|
+
};
|
|
1442
1524
|
|
|
1443
1525
|
declare type IdTuple<T> = [id: string, value: T];
|
|
1444
1526
|
declare enum CrdtType {
|
|
@@ -1488,12 +1570,14 @@ declare enum ServerMsgCode {
|
|
|
1488
1570
|
ROOM_STATE = 104,
|
|
1489
1571
|
INITIAL_STORAGE_STATE = 200,
|
|
1490
1572
|
UPDATE_STORAGE = 201,
|
|
1491
|
-
REJECT_STORAGE_OP = 299
|
|
1573
|
+
REJECT_STORAGE_OP = 299,
|
|
1574
|
+
FETCH_DOC = 300,
|
|
1575
|
+
DOC_UPDATE = 301
|
|
1492
1576
|
}
|
|
1493
1577
|
/**
|
|
1494
1578
|
* Messages that can be sent from the server to the client.
|
|
1495
1579
|
*/
|
|
1496
|
-
declare type ServerMsg<TPresence extends JsonObject, TUserMeta extends BaseUserMeta, TRoomEvent extends Json> = UpdatePresenceServerMsg<TPresence> | UserJoinServerMsg<TUserMeta> | UserLeftServerMsg | BroadcastedEventServerMsg<TRoomEvent> | RoomStateServerMsg<TUserMeta> | InitialDocumentStateServerMsg | UpdateStorageServerMsg | RejectedStorageOpServerMsg;
|
|
1580
|
+
declare type ServerMsg<TPresence extends JsonObject, TUserMeta extends BaseUserMeta, TRoomEvent extends Json> = UpdatePresenceServerMsg<TPresence> | UserJoinServerMsg<TUserMeta> | UserLeftServerMsg | BroadcastedEventServerMsg<TRoomEvent> | RoomStateServerMsg<TUserMeta> | InitialDocumentStateServerMsg | UpdateStorageServerMsg | RejectedStorageOpServerMsg | FetchDoc;
|
|
1497
1581
|
/**
|
|
1498
1582
|
* Sent by the WebSocket server and broadcasted to all clients to announce that
|
|
1499
1583
|
* a User updated their presence. For example, when a user moves their cursor.
|
|
@@ -1576,6 +1660,10 @@ declare type UserLeftServerMsg = {
|
|
|
1576
1660
|
readonly type: ServerMsgCode.USER_LEFT;
|
|
1577
1661
|
readonly actor: number;
|
|
1578
1662
|
};
|
|
1663
|
+
declare type FetchDoc = {
|
|
1664
|
+
readonly type: ServerMsgCode.FETCH_DOC;
|
|
1665
|
+
readonly data: string[];
|
|
1666
|
+
};
|
|
1579
1667
|
/**
|
|
1580
1668
|
* Sent by the WebSocket server and broadcasted to all clients to announce that
|
|
1581
1669
|
* a User broadcasted an Event to everyone in the Room.
|
|
@@ -1762,7 +1850,7 @@ declare type ClientToPanelMessage =
|
|
|
1762
1850
|
| {
|
|
1763
1851
|
msg: "room::sync::full";
|
|
1764
1852
|
roomId: string;
|
|
1765
|
-
status:
|
|
1853
|
+
status: Status;
|
|
1766
1854
|
storage: readonly LsonTreeNode[] | null;
|
|
1767
1855
|
me: UserTreeNode | null;
|
|
1768
1856
|
others: readonly UserTreeNode[];
|
|
@@ -1773,7 +1861,7 @@ declare type ClientToPanelMessage =
|
|
|
1773
1861
|
| {
|
|
1774
1862
|
msg: "room::sync::partial";
|
|
1775
1863
|
roomId: string;
|
|
1776
|
-
status?:
|
|
1864
|
+
status?: Status;
|
|
1777
1865
|
storage?: readonly LsonTreeNode[];
|
|
1778
1866
|
me?: UserTreeNode;
|
|
1779
1867
|
others?: readonly UserTreeNode[];
|
|
@@ -1824,4 +1912,4 @@ declare type EnsureJson<T> = [
|
|
|
1824
1912
|
[K in keyof T]: EnsureJson<T[K]>;
|
|
1825
1913
|
};
|
|
1826
1914
|
|
|
1827
|
-
export { AckOp, AppOnlyAuthToken, AuthToken, BaseAuthResult, BaseUserMeta, BroadcastEventClientMsg, BroadcastOptions, BroadcastedEventServerMsg, Client, ClientMsg, ClientMsgCode,
|
|
1915
|
+
export { AckOp, AppOnlyAuthToken, AuthToken, BaseAuthResult, BaseUserMeta, BroadcastEventClientMsg, BroadcastOptions, BroadcastedEventServerMsg, Client, ClientMsg, ClientMsgCode, CrdtType, CreateChildOp, CreateListOp, CreateMapOp, CreateObjectOp, CreateOp, CreateRegisterOp, CreateRootObjectOp, Delegates, DeleteCrdtOp, DeleteObjectKeyOp, DevToolsTreeNode as DevTools, protocol as DevToolsMsg, EnsureJson, FetchDocClientMsg, FetchStorageClientMsg, History, IWebSocket, IWebSocketCloseEvent, IWebSocketEvent, IWebSocketInstance, IWebSocketMessageEvent, IdTuple, Immutable, InitialDocumentStateServerMsg, Json, JsonArray, JsonObject, JsonScalar, LegacyConnectionStatus, LiveList, LiveListUpdate, LiveMap, LiveMapUpdate, LiveNode, LiveObject, LiveObjectUpdate, LiveStructure, LostConnectionEvent, Lson, LsonObject, NodeMap, Op, OpCode, Others, ParentToChildNodeMap, PlainLson, PlainLsonFields, PlainLsonList, PlainLsonMap, PlainLsonObject, RejectedStorageOpServerMsg, Resolve, Room, RoomAuthToken, RoomInitializers, RoomStateServerMsg, SerializedChild, SerializedCrdt, SerializedList, SerializedMap, SerializedObject, SerializedRegister, SerializedRootObject, ServerMsg, ServerMsgCode, SetParentKeyOp, Status, StorageStatus, StorageUpdate, ToImmutable, ToJson, UpdateDocClientMsg, UpdateObjectOp, UpdatePresenceClientMsg, UpdatePresenceServerMsg, UpdateStorageClientMsg, UpdateStorageServerMsg, User, UserJoinServerMsg, UserLeftServerMsg, WebsocketCloseCodes, asArrayWithLegacyMethods, asPos, assert, assertNever, b64decode, createClient, deprecate, deprecateIf, errorIf, freeze, isAppOnlyAuthToken, isAuthToken, isChildCrdt, isJsonArray, isJsonObject, isJsonScalar, isPlainObject, isRoomAuthToken, isRootCrdt, legacy_patchImmutableObject, lsonToJson, makePosition, nn, patchLiveObjectKey, shallow, throwUsageError, toPlainLson, tryParseJson, withTimeout };
|
package/dist/index.js
CHANGED
|
@@ -157,7 +157,7 @@ var onMessageFromPanel = eventSource.observable;
|
|
|
157
157
|
// src/devtools/index.ts
|
|
158
158
|
var VERSION = true ? (
|
|
159
159
|
/* istanbul ignore next */
|
|
160
|
-
"1.1.0-
|
|
160
|
+
"1.1.0-yjs1"
|
|
161
161
|
) : "dev";
|
|
162
162
|
var _devtoolsSetupHasRun = false;
|
|
163
163
|
function setupDevTools(getAllRooms) {
|
|
@@ -199,7 +199,7 @@ function startSyncStream(room) {
|
|
|
199
199
|
fullSync(room);
|
|
200
200
|
unsubsByRoomId.set(room.id, [
|
|
201
201
|
// When the connection status changes
|
|
202
|
-
room.events.
|
|
202
|
+
room.events.status.subscribe(() => partialSyncConnection(room)),
|
|
203
203
|
// When storage initializes, send the update
|
|
204
204
|
room.events.storageDidLoad.subscribeOnce(() => partialSyncStorage(room)),
|
|
205
205
|
// Any time storage updates, send the new storage root
|
|
@@ -213,7 +213,7 @@ function partialSyncConnection(room) {
|
|
|
213
213
|
sendToPanel({
|
|
214
214
|
msg: "room::sync::partial",
|
|
215
215
|
roomId: room.id,
|
|
216
|
-
status: room.
|
|
216
|
+
status: room.getStatus()
|
|
217
217
|
});
|
|
218
218
|
}
|
|
219
219
|
function partialSyncStorage(room) {
|
|
@@ -254,7 +254,7 @@ function fullSync(room) {
|
|
|
254
254
|
sendToPanel({
|
|
255
255
|
msg: "room::sync::full",
|
|
256
256
|
roomId: room.id,
|
|
257
|
-
status: room.
|
|
257
|
+
status: room.getStatus(),
|
|
258
258
|
storage: (_a = root == null ? void 0 : root.toTreeNode("root").payload) != null ? _a : null,
|
|
259
259
|
me,
|
|
260
260
|
others
|
|
@@ -823,22 +823,37 @@ function withTimeout(promise, millis, errmsg = "Timed out") {
|
|
|
823
823
|
}
|
|
824
824
|
|
|
825
825
|
// src/connection.ts
|
|
826
|
-
function
|
|
826
|
+
function newToLegacyStatus(status) {
|
|
827
|
+
switch (status) {
|
|
828
|
+
case "connecting":
|
|
829
|
+
return "connecting";
|
|
830
|
+
case "connected":
|
|
831
|
+
return "open";
|
|
832
|
+
case "reconnecting":
|
|
833
|
+
return "unavailable";
|
|
834
|
+
case "disconnected":
|
|
835
|
+
return "failed";
|
|
836
|
+
case "initial":
|
|
837
|
+
return "closed";
|
|
838
|
+
default:
|
|
839
|
+
return "closed";
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
function toNewConnectionStatus(machine) {
|
|
843
|
+
const state = machine.currentState;
|
|
827
844
|
switch (state) {
|
|
828
845
|
case "@ok.connected":
|
|
829
846
|
case "@ok.awaiting-pong":
|
|
830
|
-
return "
|
|
847
|
+
return "connected";
|
|
831
848
|
case "@idle.initial":
|
|
832
|
-
return "
|
|
849
|
+
return "initial";
|
|
833
850
|
case "@auth.busy":
|
|
834
851
|
case "@auth.backoff":
|
|
835
|
-
return "authenticating";
|
|
836
852
|
case "@connecting.busy":
|
|
837
|
-
return "connecting";
|
|
838
853
|
case "@connecting.backoff":
|
|
839
|
-
return "
|
|
854
|
+
return machine.context.successCount > 0 ? "reconnecting" : "connecting";
|
|
840
855
|
case "@idle.failed":
|
|
841
|
-
return "
|
|
856
|
+
return "disconnected";
|
|
842
857
|
default:
|
|
843
858
|
return assertNever(state, "Unknown state");
|
|
844
859
|
}
|
|
@@ -873,6 +888,9 @@ function increaseBackoffDelayAggressively(context) {
|
|
|
873
888
|
backoffDelay: nextBackoffDelay(context.backoffDelay, BACKOFF_DELAYS_SLOW)
|
|
874
889
|
});
|
|
875
890
|
}
|
|
891
|
+
function resetSuccessCount(context) {
|
|
892
|
+
context.patch({ successCount: 0 });
|
|
893
|
+
}
|
|
876
894
|
function log(level, message) {
|
|
877
895
|
const logger = level === 2 /* ERROR */ ? error : level === 1 /* WARN */ ? warn : (
|
|
878
896
|
/* black hole */
|
|
@@ -883,9 +901,34 @@ function log(level, message) {
|
|
|
883
901
|
logger(message);
|
|
884
902
|
};
|
|
885
903
|
}
|
|
886
|
-
function
|
|
887
|
-
|
|
888
|
-
(
|
|
904
|
+
function logPrematureErrorOrCloseEvent(e) {
|
|
905
|
+
const conn = "Connection to Liveblocks websocket server";
|
|
906
|
+
return (ctx) => {
|
|
907
|
+
if (e instanceof Error) {
|
|
908
|
+
warn(`${conn} could not be established. ${String(e)}`);
|
|
909
|
+
} else {
|
|
910
|
+
warn(
|
|
911
|
+
isCloseEvent(e) ? `${conn} closed prematurely (code: ${e.code}). Retrying in ${ctx.backoffDelay}ms.` : `${conn} could not be established.`
|
|
912
|
+
);
|
|
913
|
+
}
|
|
914
|
+
};
|
|
915
|
+
}
|
|
916
|
+
function logCloseEvent(event) {
|
|
917
|
+
return (ctx) => {
|
|
918
|
+
warn(
|
|
919
|
+
`Connection to Liveblocks websocket server closed (code: ${event.code}). Retrying in ${ctx.backoffDelay}ms.`
|
|
920
|
+
);
|
|
921
|
+
};
|
|
922
|
+
}
|
|
923
|
+
var logPermanentClose = log(
|
|
924
|
+
1 /* WARN */,
|
|
925
|
+
"Connection to WebSocket closed permanently. Won't retry."
|
|
926
|
+
);
|
|
927
|
+
function isCloseEvent(error2) {
|
|
928
|
+
return !(error2 instanceof Error) && error2.type === "close";
|
|
929
|
+
}
|
|
930
|
+
function isCustomCloseEvent(error2) {
|
|
931
|
+
return isCloseEvent(error2) && error2.code >= 4e3 && error2.code < 4100;
|
|
889
932
|
}
|
|
890
933
|
function enableTracing(machine) {
|
|
891
934
|
const start = (/* @__PURE__ */ new Date()).getTime();
|
|
@@ -916,16 +959,18 @@ function defineConnectivityEvents(machine) {
|
|
|
916
959
|
const statusDidChange = makeEventSource();
|
|
917
960
|
const didConnect = makeEventSource();
|
|
918
961
|
const didDisconnect = makeEventSource();
|
|
919
|
-
let
|
|
920
|
-
const unsubscribe = machine.events.didEnterState.subscribe((
|
|
921
|
-
const
|
|
922
|
-
|
|
923
|
-
|
|
962
|
+
let lastStatus = null;
|
|
963
|
+
const unsubscribe = machine.events.didEnterState.subscribe(() => {
|
|
964
|
+
const currStatus = toNewConnectionStatus(machine);
|
|
965
|
+
if (currStatus !== lastStatus) {
|
|
966
|
+
statusDidChange.notify(currStatus);
|
|
967
|
+
}
|
|
968
|
+
if (lastStatus === "connected" && currStatus !== "connected") {
|
|
924
969
|
didDisconnect.notify();
|
|
925
|
-
} else if (
|
|
970
|
+
} else if (lastStatus !== "connected" && currStatus === "connected") {
|
|
926
971
|
didConnect.notify();
|
|
927
972
|
}
|
|
928
|
-
|
|
973
|
+
lastStatus = currStatus;
|
|
929
974
|
});
|
|
930
975
|
return {
|
|
931
976
|
statusDidChange: statusDidChange.observable,
|
|
@@ -940,6 +985,7 @@ function createConnectionStateMachine(delegates, enableDebugLogging) {
|
|
|
940
985
|
onMessage.pause();
|
|
941
986
|
const onLiveblocksError = makeEventSource();
|
|
942
987
|
const initialContext = {
|
|
988
|
+
successCount: 0,
|
|
943
989
|
token: null,
|
|
944
990
|
socket: null,
|
|
945
991
|
backoffDelay: RESET_DELAY
|
|
@@ -948,11 +994,11 @@ function createConnectionStateMachine(delegates, enableDebugLogging) {
|
|
|
948
994
|
machine.addTransitions("*", {
|
|
949
995
|
RECONNECT: {
|
|
950
996
|
target: "@auth.backoff",
|
|
951
|
-
effect: increaseBackoffDelay
|
|
997
|
+
effect: [increaseBackoffDelay, resetSuccessCount]
|
|
952
998
|
},
|
|
953
999
|
DISCONNECT: "@idle.initial"
|
|
954
1000
|
});
|
|
955
|
-
machine.addTransitions("@idle.*", {
|
|
1001
|
+
machine.onEnter("@idle.*", resetSuccessCount).addTransitions("@idle.*", {
|
|
956
1002
|
CONNECT: (_, ctx) => (
|
|
957
1003
|
// If we still have a known token, try to reconnect to the socket directly,
|
|
958
1004
|
// otherwise, try to obtain a new token
|
|
@@ -1097,41 +1143,41 @@ function createConnectionStateMachine(delegates, enableDebugLogging) {
|
|
|
1097
1143
|
effect: log(2 /* ERROR */, err.message)
|
|
1098
1144
|
};
|
|
1099
1145
|
}
|
|
1146
|
+
if (isCloseEvent(err) && err.code === 4999) {
|
|
1147
|
+
return {
|
|
1148
|
+
target: "@idle.failed",
|
|
1149
|
+
effect: log(2 /* ERROR */, err.reason)
|
|
1150
|
+
};
|
|
1151
|
+
}
|
|
1152
|
+
if (isCustomCloseEvent(err) && err.code !== 4001) {
|
|
1153
|
+
return {
|
|
1154
|
+
target: "@connecting.backoff",
|
|
1155
|
+
effect: [
|
|
1156
|
+
increaseBackoffDelayAggressively,
|
|
1157
|
+
logPrematureErrorOrCloseEvent(err)
|
|
1158
|
+
]
|
|
1159
|
+
};
|
|
1160
|
+
}
|
|
1100
1161
|
return {
|
|
1101
1162
|
target: "@auth.backoff",
|
|
1102
|
-
effect: [
|
|
1103
|
-
// Increase the backoff delay conditionally
|
|
1104
|
-
// TODO: This is ugly. DRY this up with the other code 40xx checks elsewhere.
|
|
1105
|
-
!(err instanceof Error) && err.type === "close" && err.code >= 4e3 && err.code <= 4100 ? increaseBackoffDelayAggressively : increaseBackoffDelay,
|
|
1106
|
-
// Produce a useful log message
|
|
1107
|
-
(ctx) => {
|
|
1108
|
-
if (err instanceof Error) {
|
|
1109
|
-
warn(String(err));
|
|
1110
|
-
} else {
|
|
1111
|
-
warn(
|
|
1112
|
-
err.type === "close" ? `Connection to Liveblocks websocket server closed prematurely (code: ${err.code}). Retrying in ${ctx.backoffDelay}ms.` : "Connection to Liveblocks websocket server could not be established."
|
|
1113
|
-
);
|
|
1114
|
-
}
|
|
1115
|
-
}
|
|
1116
|
-
]
|
|
1163
|
+
effect: [increaseBackoffDelay, logPrematureErrorOrCloseEvent(err)]
|
|
1117
1164
|
};
|
|
1118
1165
|
}
|
|
1119
1166
|
);
|
|
1120
|
-
|
|
1167
|
+
const sendHeartbeat = {
|
|
1121
1168
|
target: "@ok.awaiting-pong",
|
|
1122
|
-
effect:
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
const noPongAction = {
|
|
1127
|
-
target: "@connecting.busy",
|
|
1128
|
-
// Log implicit connection loss and drop the current open socket
|
|
1129
|
-
effect: log(
|
|
1130
|
-
1 /* WARN */,
|
|
1131
|
-
"Received no pong from server, assume implicit connection loss."
|
|
1132
|
-
)
|
|
1169
|
+
effect: (ctx) => {
|
|
1170
|
+
var _a;
|
|
1171
|
+
(_a = ctx.socket) == null ? void 0 : _a.send("ping");
|
|
1172
|
+
}
|
|
1133
1173
|
};
|
|
1134
|
-
machine.
|
|
1174
|
+
machine.addTimedTransition("@ok.connected", HEARTBEAT_INTERVAL, sendHeartbeat).addTransitions("@ok.connected", {
|
|
1175
|
+
NAVIGATOR_OFFLINE: sendHeartbeat,
|
|
1176
|
+
// Don't take the browser's word for it when it says it's offline. Do a ping/pong to make sure.
|
|
1177
|
+
WINDOW_GOT_FOCUS: sendHeartbeat
|
|
1178
|
+
});
|
|
1179
|
+
machine.onEnter("@ok.*", (ctx) => {
|
|
1180
|
+
ctx.patch({ successCount: ctx.successCount + 1 });
|
|
1135
1181
|
const timerID = setTimeout(
|
|
1136
1182
|
// On the next tick, start delivering all messages that have already
|
|
1137
1183
|
// been received, and continue synchronous delivery of all future
|
|
@@ -1139,13 +1185,20 @@ function createConnectionStateMachine(delegates, enableDebugLogging) {
|
|
|
1139
1185
|
onMessage.unpause,
|
|
1140
1186
|
0
|
|
1141
1187
|
);
|
|
1142
|
-
return (
|
|
1143
|
-
teardownSocket(
|
|
1144
|
-
|
|
1188
|
+
return (ctx2) => {
|
|
1189
|
+
teardownSocket(ctx2.socket);
|
|
1190
|
+
ctx2.patch({ socket: null });
|
|
1145
1191
|
clearTimeout(timerID);
|
|
1146
1192
|
onMessage.pause();
|
|
1147
1193
|
};
|
|
1148
|
-
}).
|
|
1194
|
+
}).addTransitions("@ok.awaiting-pong", { PONG: "@ok.connected" }).addTimedTransition("@ok.awaiting-pong", PONG_TIMEOUT, {
|
|
1195
|
+
target: "@connecting.busy",
|
|
1196
|
+
// Log implicit connection loss and drop the current open socket
|
|
1197
|
+
effect: log(
|
|
1198
|
+
1 /* WARN */,
|
|
1199
|
+
"Received no pong from server, assume implicit connection loss."
|
|
1200
|
+
)
|
|
1201
|
+
}).addTransitions("@ok.*", {
|
|
1149
1202
|
// When a socket receives an error, this can cause the closing of the
|
|
1150
1203
|
// socket, or not. So always check to see if the socket is still OPEN or
|
|
1151
1204
|
// not. When still OPEN, don't transition.
|
|
@@ -1163,37 +1216,31 @@ function createConnectionStateMachine(delegates, enableDebugLogging) {
|
|
|
1163
1216
|
if (e.event.code === 4999) {
|
|
1164
1217
|
return {
|
|
1165
1218
|
target: "@idle.failed",
|
|
1166
|
-
effect:
|
|
1167
|
-
1 /* WARN */,
|
|
1168
|
-
"Connection to WebSocket closed permanently. Won't retry."
|
|
1169
|
-
)
|
|
1219
|
+
effect: logPermanentClose
|
|
1170
1220
|
};
|
|
1171
1221
|
}
|
|
1172
|
-
if (e.event.code
|
|
1222
|
+
if (e.event.code === 4001) {
|
|
1223
|
+
return {
|
|
1224
|
+
target: "@auth.backoff",
|
|
1225
|
+
effect: [increaseBackoffDelay, logCloseEvent(e.event)]
|
|
1226
|
+
};
|
|
1227
|
+
}
|
|
1228
|
+
if (isCustomCloseEvent(e.event)) {
|
|
1173
1229
|
return {
|
|
1174
1230
|
target: "@connecting.backoff",
|
|
1175
1231
|
effect: [
|
|
1176
1232
|
increaseBackoffDelayAggressively,
|
|
1177
|
-
(
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
if (event.code >= 4e3 && event.code <= 4100) {
|
|
1182
|
-
const err = new LiveblocksError(event.reason, event.code);
|
|
1183
|
-
onLiveblocksError.notify(err);
|
|
1184
|
-
}
|
|
1233
|
+
logCloseEvent(e.event),
|
|
1234
|
+
() => {
|
|
1235
|
+
const err = new LiveblocksError(e.event.reason, e.event.code);
|
|
1236
|
+
onLiveblocksError.notify(err);
|
|
1185
1237
|
}
|
|
1186
1238
|
]
|
|
1187
1239
|
};
|
|
1188
1240
|
}
|
|
1189
1241
|
return {
|
|
1190
1242
|
target: "@connecting.backoff",
|
|
1191
|
-
effect: [
|
|
1192
|
-
increaseBackoffDelay,
|
|
1193
|
-
(ctx) => warn(
|
|
1194
|
-
`Connection to Liveblocks websocket server closed (code: ${e.event.code}). Retrying in ${ctx.backoffDelay}ms.`
|
|
1195
|
-
)
|
|
1196
|
-
]
|
|
1243
|
+
effect: [increaseBackoffDelay, logCloseEvent(e.event)]
|
|
1197
1244
|
};
|
|
1198
1245
|
}
|
|
1199
1246
|
});
|
|
@@ -1202,7 +1249,10 @@ function createConnectionStateMachine(delegates, enableDebugLogging) {
|
|
|
1202
1249
|
const win = typeof window !== "undefined" ? window : void 0;
|
|
1203
1250
|
const root = win != null ? win : doc;
|
|
1204
1251
|
machine.onEnter("*", (ctx) => {
|
|
1205
|
-
function
|
|
1252
|
+
function onNetworkOffline() {
|
|
1253
|
+
machine.send({ type: "NAVIGATOR_OFFLINE" });
|
|
1254
|
+
}
|
|
1255
|
+
function onNetworkBackOnline() {
|
|
1206
1256
|
machine.send({ type: "NAVIGATOR_ONLINE" });
|
|
1207
1257
|
}
|
|
1208
1258
|
function onVisibilityChange() {
|
|
@@ -1210,11 +1260,13 @@ function createConnectionStateMachine(delegates, enableDebugLogging) {
|
|
|
1210
1260
|
machine.send({ type: "WINDOW_GOT_FOCUS" });
|
|
1211
1261
|
}
|
|
1212
1262
|
}
|
|
1213
|
-
win == null ? void 0 : win.addEventListener("online",
|
|
1263
|
+
win == null ? void 0 : win.addEventListener("online", onNetworkBackOnline);
|
|
1264
|
+
win == null ? void 0 : win.addEventListener("offline", onNetworkOffline);
|
|
1214
1265
|
root == null ? void 0 : root.addEventListener("visibilitychange", onVisibilityChange);
|
|
1215
1266
|
return () => {
|
|
1216
1267
|
root == null ? void 0 : root.removeEventListener("visibilitychange", onVisibilityChange);
|
|
1217
|
-
win == null ? void 0 : win.removeEventListener("online",
|
|
1268
|
+
win == null ? void 0 : win.removeEventListener("online", onNetworkBackOnline);
|
|
1269
|
+
win == null ? void 0 : win.removeEventListener("offline", onNetworkOffline);
|
|
1218
1270
|
teardownSocket(ctx.socket);
|
|
1219
1271
|
};
|
|
1220
1272
|
});
|
|
@@ -1249,22 +1301,21 @@ var ManagedSocket = class {
|
|
|
1249
1301
|
this.events = events;
|
|
1250
1302
|
this.cleanups = cleanups;
|
|
1251
1303
|
}
|
|
1252
|
-
|
|
1304
|
+
getLegacyStatus() {
|
|
1305
|
+
return newToLegacyStatus(this.getStatus());
|
|
1306
|
+
}
|
|
1307
|
+
getStatus() {
|
|
1253
1308
|
try {
|
|
1254
|
-
return
|
|
1309
|
+
return toNewConnectionStatus(this.machine);
|
|
1255
1310
|
} catch (e) {
|
|
1256
|
-
return "
|
|
1311
|
+
return "initial";
|
|
1257
1312
|
}
|
|
1258
1313
|
}
|
|
1259
1314
|
/**
|
|
1260
1315
|
* Returns the current auth token.
|
|
1261
1316
|
*/
|
|
1262
1317
|
get token() {
|
|
1263
|
-
|
|
1264
|
-
if (tok === null) {
|
|
1265
|
-
throw new Error("Unexpected null token here");
|
|
1266
|
-
}
|
|
1267
|
-
return tok;
|
|
1318
|
+
return this.machine.context.token;
|
|
1268
1319
|
}
|
|
1269
1320
|
/**
|
|
1270
1321
|
* Call this method to try to connect to a WebSocket. This only has an effect
|
|
@@ -3935,6 +3986,8 @@ var ClientMsgCode = /* @__PURE__ */ ((ClientMsgCode2) => {
|
|
|
3935
3986
|
ClientMsgCode2[ClientMsgCode2["BROADCAST_EVENT"] = 103] = "BROADCAST_EVENT";
|
|
3936
3987
|
ClientMsgCode2[ClientMsgCode2["FETCH_STORAGE"] = 200] = "FETCH_STORAGE";
|
|
3937
3988
|
ClientMsgCode2[ClientMsgCode2["UPDATE_STORAGE"] = 201] = "UPDATE_STORAGE";
|
|
3989
|
+
ClientMsgCode2[ClientMsgCode2["FETCH_DOC"] = 300] = "FETCH_DOC";
|
|
3990
|
+
ClientMsgCode2[ClientMsgCode2["UPDATE_DOC"] = 301] = "UPDATE_DOC";
|
|
3938
3991
|
return ClientMsgCode2;
|
|
3939
3992
|
})(ClientMsgCode || {});
|
|
3940
3993
|
|
|
@@ -3948,6 +4001,8 @@ var ServerMsgCode = /* @__PURE__ */ ((ServerMsgCode2) => {
|
|
|
3948
4001
|
ServerMsgCode2[ServerMsgCode2["INITIAL_STORAGE_STATE"] = 200] = "INITIAL_STORAGE_STATE";
|
|
3949
4002
|
ServerMsgCode2[ServerMsgCode2["UPDATE_STORAGE"] = 201] = "UPDATE_STORAGE";
|
|
3950
4003
|
ServerMsgCode2[ServerMsgCode2["REJECT_STORAGE_OP"] = 299] = "REJECT_STORAGE_OP";
|
|
4004
|
+
ServerMsgCode2[ServerMsgCode2["FETCH_DOC"] = 300] = "FETCH_DOC";
|
|
4005
|
+
ServerMsgCode2[ServerMsgCode2["DOC_UPDATE"] = 301] = "DOC_UPDATE";
|
|
3951
4006
|
return ServerMsgCode2;
|
|
3952
4007
|
})(ServerMsgCode || {});
|
|
3953
4008
|
|
|
@@ -4173,9 +4228,6 @@ function makeIdFactory(connectionId) {
|
|
|
4173
4228
|
let count = 0;
|
|
4174
4229
|
return () => `${connectionId}:${count++}`;
|
|
4175
4230
|
}
|
|
4176
|
-
function isConnectionSelfAware(connection) {
|
|
4177
|
-
return connection.status === "open" || connection.status === "connecting";
|
|
4178
|
-
}
|
|
4179
4231
|
function userToTreeNode(key, user) {
|
|
4180
4232
|
return {
|
|
4181
4233
|
type: "User",
|
|
@@ -4204,7 +4256,6 @@ function createRoom(options, config) {
|
|
|
4204
4256
|
config.enableDebugLogging
|
|
4205
4257
|
);
|
|
4206
4258
|
const context = {
|
|
4207
|
-
lastConnectionId: null,
|
|
4208
4259
|
buffer: {
|
|
4209
4260
|
flushTimerID: void 0,
|
|
4210
4261
|
lastFlushedAt: 0,
|
|
@@ -4218,7 +4269,7 @@ function createRoom(options, config) {
|
|
|
4218
4269
|
messages: [],
|
|
4219
4270
|
storageOperations: []
|
|
4220
4271
|
},
|
|
4221
|
-
|
|
4272
|
+
sessionInfo: new ValueRef(null),
|
|
4222
4273
|
me: new MeRef(initialPresence),
|
|
4223
4274
|
others: new OthersRef(),
|
|
4224
4275
|
initialStorage,
|
|
@@ -4238,55 +4289,78 @@ function createRoom(options, config) {
|
|
|
4238
4289
|
};
|
|
4239
4290
|
const doNotBatchUpdates = (cb) => cb();
|
|
4240
4291
|
const batchUpdates = (_d = config.unstable_batchedUpdates) != null ? _d : doNotBatchUpdates;
|
|
4292
|
+
let lastToken;
|
|
4241
4293
|
function onStatusDidChange(newStatus) {
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4294
|
+
var _a2;
|
|
4295
|
+
const token = (_a2 = managedSocket.token) == null ? void 0 : _a2.parsed;
|
|
4296
|
+
if (token !== void 0 && token !== lastToken) {
|
|
4297
|
+
context.sessionInfo.set({
|
|
4298
|
+
id: token.actor,
|
|
4299
|
+
userInfo: token.info,
|
|
4300
|
+
userId: token.id,
|
|
4301
|
+
isReadOnly: isStorageReadOnly(token.scopes)
|
|
4249
4302
|
});
|
|
4250
|
-
|
|
4251
|
-
context.connection.set({ status: newStatus });
|
|
4303
|
+
lastToken = token;
|
|
4252
4304
|
}
|
|
4253
4305
|
batchUpdates(() => {
|
|
4254
|
-
eventHub.
|
|
4306
|
+
eventHub.status.notify(newStatus);
|
|
4307
|
+
eventHub.connection.notify(newToLegacyStatus(newStatus));
|
|
4255
4308
|
});
|
|
4256
4309
|
}
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4310
|
+
let _connectionLossTimerId;
|
|
4311
|
+
let _hasLostConnection = false;
|
|
4312
|
+
function handleConnectionLossEvent(newStatus) {
|
|
4313
|
+
if (newStatus === "reconnecting") {
|
|
4314
|
+
_connectionLossTimerId = setTimeout(() => {
|
|
4315
|
+
batchUpdates(() => {
|
|
4316
|
+
eventHub.lostConnection.notify("lost");
|
|
4317
|
+
_hasLostConnection = true;
|
|
4318
|
+
context.others.clearOthers();
|
|
4319
|
+
notify({ others: [{ type: "reset" }] }, doNotBatchUpdates);
|
|
4320
|
+
});
|
|
4321
|
+
}, config.lostConnectionTimeout);
|
|
4322
|
+
} else {
|
|
4323
|
+
clearTimeout(_connectionLossTimerId);
|
|
4324
|
+
if (_hasLostConnection) {
|
|
4325
|
+
if (newStatus === "disconnected") {
|
|
4326
|
+
batchUpdates(() => {
|
|
4327
|
+
eventHub.lostConnection.notify("failed");
|
|
4328
|
+
});
|
|
4329
|
+
} else {
|
|
4330
|
+
batchUpdates(() => {
|
|
4331
|
+
eventHub.lostConnection.notify("restored");
|
|
4332
|
+
});
|
|
4333
|
+
}
|
|
4334
|
+
_hasLostConnection = false;
|
|
4335
|
+
}
|
|
4273
4336
|
}
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
|
|
4337
|
+
}
|
|
4338
|
+
function onDidConnect() {
|
|
4339
|
+
const sessionInfo = context.sessionInfo.current;
|
|
4340
|
+
if (sessionInfo === null) {
|
|
4341
|
+
throw new Error("Unexpected missing session info");
|
|
4342
|
+
}
|
|
4343
|
+
context.buffer.me = {
|
|
4344
|
+
type: "full",
|
|
4345
|
+
data: (
|
|
4346
|
+
// Because context.me.current is a readonly object, we'll have to
|
|
4347
|
+
// make a copy here. Otherwise, type errors happen later when
|
|
4348
|
+
// "patching" my presence.
|
|
4349
|
+
__spreadValues({}, context.me.current)
|
|
4350
|
+
)
|
|
4351
|
+
};
|
|
4352
|
+
context.idFactory = makeIdFactory(sessionInfo.id);
|
|
4353
|
+
if (_getStorage$ !== null) {
|
|
4354
|
+
refreshStorage({ flush: false });
|
|
4278
4355
|
}
|
|
4279
|
-
|
|
4356
|
+
flushNowOrSoon();
|
|
4280
4357
|
}
|
|
4281
4358
|
function onDidDisconnect() {
|
|
4282
4359
|
clearTimeout(context.buffer.flushTimerID);
|
|
4283
|
-
batchUpdates(() => {
|
|
4284
|
-
context.others.clearOthers();
|
|
4285
|
-
notify({ others: [{ type: "reset" }] }, doNotBatchUpdates);
|
|
4286
|
-
});
|
|
4287
4360
|
}
|
|
4288
4361
|
managedSocket.events.onMessage.subscribe(handleServerMessage);
|
|
4289
4362
|
managedSocket.events.statusDidChange.subscribe(onStatusDidChange);
|
|
4363
|
+
managedSocket.events.statusDidChange.subscribe(handleConnectionLossEvent);
|
|
4290
4364
|
managedSocket.events.didConnect.subscribe(onDidConnect);
|
|
4291
4365
|
managedSocket.events.didDisconnect.subscribe(onDidDisconnect);
|
|
4292
4366
|
managedSocket.events.onLiveblocksError.subscribe((err) => {
|
|
@@ -4340,7 +4414,8 @@ function createRoom(options, config) {
|
|
|
4340
4414
|
}
|
|
4341
4415
|
},
|
|
4342
4416
|
assertStorageIsWritable: () => {
|
|
4343
|
-
|
|
4417
|
+
var _a2;
|
|
4418
|
+
if ((_a2 = context.sessionInfo.current) == null ? void 0 : _a2.isReadOnly) {
|
|
4344
4419
|
throw new Error(
|
|
4345
4420
|
"Cannot write to storage with a read only user, please ensure the user has write permissions"
|
|
4346
4421
|
);
|
|
@@ -4348,22 +4423,27 @@ function createRoom(options, config) {
|
|
|
4348
4423
|
}
|
|
4349
4424
|
};
|
|
4350
4425
|
const eventHub = {
|
|
4426
|
+
connection: makeEventSource(),
|
|
4427
|
+
// Old/deprecated API
|
|
4428
|
+
status: makeEventSource(),
|
|
4429
|
+
// New/recommended API
|
|
4430
|
+
lostConnection: makeEventSource(),
|
|
4351
4431
|
customEvent: makeEventSource(),
|
|
4352
4432
|
me: makeEventSource(),
|
|
4353
4433
|
others: makeEventSource(),
|
|
4354
4434
|
error: makeEventSource(),
|
|
4355
|
-
connection: makeEventSource(),
|
|
4356
4435
|
storage: makeEventSource(),
|
|
4357
4436
|
history: makeEventSource(),
|
|
4358
4437
|
storageDidLoad: makeEventSource(),
|
|
4359
|
-
storageStatus: makeEventSource()
|
|
4438
|
+
storageStatus: makeEventSource(),
|
|
4439
|
+
docUpdated: makeEventSource()
|
|
4360
4440
|
};
|
|
4361
4441
|
function sendMessages(messageOrMessages) {
|
|
4362
|
-
var _a2;
|
|
4442
|
+
var _a2, _b2;
|
|
4363
4443
|
const message = JSON.stringify(messageOrMessages);
|
|
4364
4444
|
if (config.unstable_fallbackToHTTP) {
|
|
4365
4445
|
const size = new TextEncoder().encode(message).length;
|
|
4366
|
-
if (size > MAX_MESSAGE_SIZE && managedSocket.token.raw && config.httpSendEndpoint) {
|
|
4446
|
+
if (size > MAX_MESSAGE_SIZE && ((_a2 = managedSocket.token) == null ? void 0 : _a2.raw) && config.httpSendEndpoint) {
|
|
4367
4447
|
if (isTokenExpired(managedSocket.token.parsed)) {
|
|
4368
4448
|
return managedSocket.reconnect();
|
|
4369
4449
|
}
|
|
@@ -4371,7 +4451,7 @@ function createRoom(options, config) {
|
|
|
4371
4451
|
message,
|
|
4372
4452
|
managedSocket.token.raw,
|
|
4373
4453
|
config.httpSendEndpoint,
|
|
4374
|
-
(
|
|
4454
|
+
(_b2 = config.polyfills) == null ? void 0 : _b2.fetch
|
|
4375
4455
|
);
|
|
4376
4456
|
warn(
|
|
4377
4457
|
"Message was too large for websockets and sent over HTTP instead"
|
|
@@ -4382,15 +4462,17 @@ function createRoom(options, config) {
|
|
|
4382
4462
|
managedSocket.send(message);
|
|
4383
4463
|
}
|
|
4384
4464
|
const self = new DerivedRef(
|
|
4385
|
-
context.
|
|
4465
|
+
context.sessionInfo,
|
|
4386
4466
|
context.me,
|
|
4387
|
-
(
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4467
|
+
(info, me) => {
|
|
4468
|
+
return info !== null ? {
|
|
4469
|
+
connectionId: info.id,
|
|
4470
|
+
id: info.userId,
|
|
4471
|
+
info: info.userInfo,
|
|
4472
|
+
presence: me,
|
|
4473
|
+
isReadOnly: info.isReadOnly
|
|
4474
|
+
} : null;
|
|
4475
|
+
}
|
|
4394
4476
|
);
|
|
4395
4477
|
const selfAsTreeNode = new DerivedRef(
|
|
4396
4478
|
self,
|
|
@@ -4400,7 +4482,7 @@ function createRoom(options, config) {
|
|
|
4400
4482
|
if (message.items.length === 0) {
|
|
4401
4483
|
throw new Error("Internal error: cannot load storage without items");
|
|
4402
4484
|
}
|
|
4403
|
-
if (context.root) {
|
|
4485
|
+
if (context.root !== void 0) {
|
|
4404
4486
|
updateRoot(message.items, batchedUpdatesWrapper);
|
|
4405
4487
|
} else {
|
|
4406
4488
|
context.root = LiveObject._fromItems(message.items, pool);
|
|
@@ -4412,7 +4494,7 @@ function createRoom(options, config) {
|
|
|
4412
4494
|
}
|
|
4413
4495
|
}
|
|
4414
4496
|
function updateRoot(items, batchedUpdatesWrapper) {
|
|
4415
|
-
if (
|
|
4497
|
+
if (context.root === void 0) {
|
|
4416
4498
|
return;
|
|
4417
4499
|
}
|
|
4418
4500
|
const currentItems = /* @__PURE__ */ new Map();
|
|
@@ -4459,11 +4541,9 @@ function createRoom(options, config) {
|
|
|
4459
4541
|
});
|
|
4460
4542
|
}
|
|
4461
4543
|
function getConnectionId() {
|
|
4462
|
-
const
|
|
4463
|
-
if (
|
|
4464
|
-
return
|
|
4465
|
-
} else if (context.lastConnectionId !== null) {
|
|
4466
|
-
return context.lastConnectionId;
|
|
4544
|
+
const info = context.sessionInfo.current;
|
|
4545
|
+
if (info) {
|
|
4546
|
+
return info.id;
|
|
4467
4547
|
}
|
|
4468
4548
|
throw new Error(
|
|
4469
4549
|
"Internal. Tried to get connection id but connection was never open"
|
|
@@ -4612,7 +4692,7 @@ function createRoom(options, config) {
|
|
|
4612
4692
|
}
|
|
4613
4693
|
context.activeBatch.updates.presence = true;
|
|
4614
4694
|
} else {
|
|
4615
|
-
|
|
4695
|
+
flushNowOrSoon();
|
|
4616
4696
|
batchUpdates(() => {
|
|
4617
4697
|
if (options2 == null ? void 0 : options2.addToHistory) {
|
|
4618
4698
|
addToUndoStack(
|
|
@@ -4699,7 +4779,7 @@ function createRoom(options, config) {
|
|
|
4699
4779
|
data: context.me.current,
|
|
4700
4780
|
targetActor: message.actor
|
|
4701
4781
|
});
|
|
4702
|
-
|
|
4782
|
+
flushNowOrSoon();
|
|
4703
4783
|
const user = context.others.getUser(message.actor);
|
|
4704
4784
|
return user ? { type: "enter", user } : void 0;
|
|
4705
4785
|
}
|
|
@@ -4777,6 +4857,10 @@ function createRoom(options, config) {
|
|
|
4777
4857
|
}
|
|
4778
4858
|
break;
|
|
4779
4859
|
}
|
|
4860
|
+
case 300 /* FETCH_DOC */: {
|
|
4861
|
+
eventHub.docUpdated.notify(message.data);
|
|
4862
|
+
break;
|
|
4863
|
+
}
|
|
4780
4864
|
case 104 /* ROOM_STATE */: {
|
|
4781
4865
|
updates.others.push(onRoomStateMessage(message));
|
|
4782
4866
|
break;
|
|
@@ -4785,9 +4869,7 @@ function createRoom(options, config) {
|
|
|
4785
4869
|
const unacknowledgedOps = new Map(context.unacknowledgedOps);
|
|
4786
4870
|
createOrUpdateRootFromMessage(message, doNotBatchUpdates);
|
|
4787
4871
|
applyAndSendOps(unacknowledgedOps, doNotBatchUpdates);
|
|
4788
|
-
|
|
4789
|
-
_getInitialStateResolver();
|
|
4790
|
-
}
|
|
4872
|
+
_resolveStoragePromise == null ? void 0 : _resolveStoragePromise();
|
|
4791
4873
|
notifyStorageStatus();
|
|
4792
4874
|
eventHub.storageDidLoad.notify();
|
|
4793
4875
|
break;
|
|
@@ -4834,7 +4916,7 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
4834
4916
|
notify(updates, doNotBatchUpdates);
|
|
4835
4917
|
});
|
|
4836
4918
|
}
|
|
4837
|
-
function
|
|
4919
|
+
function flushNowOrSoon() {
|
|
4838
4920
|
const storageOps = context.buffer.storageOperations;
|
|
4839
4921
|
if (storageOps.length > 0) {
|
|
4840
4922
|
for (const op of storageOps) {
|
|
@@ -4842,7 +4924,7 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
4842
4924
|
}
|
|
4843
4925
|
notifyStorageStatus();
|
|
4844
4926
|
}
|
|
4845
|
-
if (managedSocket.
|
|
4927
|
+
if (managedSocket.getStatus() !== "connected") {
|
|
4846
4928
|
context.buffer.storageOperations = [];
|
|
4847
4929
|
return;
|
|
4848
4930
|
}
|
|
@@ -4864,7 +4946,7 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
4864
4946
|
} else {
|
|
4865
4947
|
clearTimeout(context.buffer.flushTimerID);
|
|
4866
4948
|
context.buffer.flushTimerID = setTimeout(
|
|
4867
|
-
|
|
4949
|
+
flushNowOrSoon,
|
|
4868
4950
|
config.throttleDelay - elapsedMillis
|
|
4869
4951
|
);
|
|
4870
4952
|
}
|
|
@@ -4897,34 +4979,49 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
4897
4979
|
}
|
|
4898
4980
|
return messages;
|
|
4899
4981
|
}
|
|
4982
|
+
function updateDoc(data) {
|
|
4983
|
+
context.buffer.messages.push({
|
|
4984
|
+
type: 301 /* UPDATE_DOC */,
|
|
4985
|
+
data
|
|
4986
|
+
});
|
|
4987
|
+
flushNowOrSoon();
|
|
4988
|
+
}
|
|
4900
4989
|
function broadcastEvent(event, options2 = {
|
|
4901
4990
|
shouldQueueEventIfNotReady: false
|
|
4902
4991
|
}) {
|
|
4903
|
-
if (managedSocket.
|
|
4992
|
+
if (managedSocket.getStatus() !== "connected" && !options2.shouldQueueEventIfNotReady) {
|
|
4904
4993
|
return;
|
|
4905
4994
|
}
|
|
4906
4995
|
context.buffer.messages.push({
|
|
4907
4996
|
type: 103 /* BROADCAST_EVENT */,
|
|
4908
4997
|
event
|
|
4909
4998
|
});
|
|
4910
|
-
|
|
4999
|
+
flushNowOrSoon();
|
|
4911
5000
|
}
|
|
4912
5001
|
function dispatchOps(ops) {
|
|
4913
5002
|
context.buffer.storageOperations.push(...ops);
|
|
4914
|
-
|
|
5003
|
+
flushNowOrSoon();
|
|
5004
|
+
}
|
|
5005
|
+
let _getStorage$ = null;
|
|
5006
|
+
let _resolveStoragePromise = null;
|
|
5007
|
+
function refreshStorage(options2) {
|
|
5008
|
+
const messages = context.buffer.messages;
|
|
5009
|
+
if (!messages.some((msg) => msg.type === 200 /* FETCH_STORAGE */)) {
|
|
5010
|
+
messages.push({ type: 200 /* FETCH_STORAGE */ });
|
|
5011
|
+
}
|
|
5012
|
+
if (options2.flush) {
|
|
5013
|
+
flushNowOrSoon();
|
|
5014
|
+
}
|
|
4915
5015
|
}
|
|
4916
|
-
let _getInitialStatePromise = null;
|
|
4917
|
-
let _getInitialStateResolver = null;
|
|
4918
5016
|
function startLoadingStorage() {
|
|
4919
|
-
if (
|
|
4920
|
-
|
|
4921
|
-
|
|
4922
|
-
|
|
4923
|
-
|
|
4924
|
-
);
|
|
5017
|
+
if (_getStorage$ === null) {
|
|
5018
|
+
refreshStorage({ flush: true });
|
|
5019
|
+
_getStorage$ = new Promise((resolve) => {
|
|
5020
|
+
_resolveStoragePromise = resolve;
|
|
5021
|
+
});
|
|
4925
5022
|
notifyStorageStatus();
|
|
4926
5023
|
}
|
|
4927
|
-
return
|
|
5024
|
+
return _getStorage$;
|
|
4928
5025
|
}
|
|
4929
5026
|
function getStorageSnapshot() {
|
|
4930
5027
|
const root = context.root;
|
|
@@ -4937,7 +5034,7 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
4937
5034
|
}
|
|
4938
5035
|
function getStorage() {
|
|
4939
5036
|
return __async(this, null, function* () {
|
|
4940
|
-
if (context.root) {
|
|
5037
|
+
if (context.root !== void 0) {
|
|
4941
5038
|
return Promise.resolve({
|
|
4942
5039
|
root: context.root
|
|
4943
5040
|
});
|
|
@@ -4948,6 +5045,10 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
4948
5045
|
};
|
|
4949
5046
|
});
|
|
4950
5047
|
}
|
|
5048
|
+
function getDoc(vector = "") {
|
|
5049
|
+
context.buffer.messages.push({ type: 300 /* FETCH_DOC */, vector });
|
|
5050
|
+
flushNowOrSoon();
|
|
5051
|
+
}
|
|
4951
5052
|
function undo() {
|
|
4952
5053
|
if (context.activeBatch) {
|
|
4953
5054
|
throw new Error("undo is not allowed during a batch");
|
|
@@ -4968,7 +5069,7 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
4968
5069
|
context.buffer.storageOperations.push(op);
|
|
4969
5070
|
}
|
|
4970
5071
|
}
|
|
4971
|
-
|
|
5072
|
+
flushNowOrSoon();
|
|
4972
5073
|
}
|
|
4973
5074
|
function redo() {
|
|
4974
5075
|
if (context.activeBatch) {
|
|
@@ -4990,7 +5091,7 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
4990
5091
|
context.buffer.storageOperations.push(op);
|
|
4991
5092
|
}
|
|
4992
5093
|
}
|
|
4993
|
-
|
|
5094
|
+
flushNowOrSoon();
|
|
4994
5095
|
}
|
|
4995
5096
|
function batch(callback) {
|
|
4996
5097
|
if (context.activeBatch) {
|
|
@@ -5022,7 +5123,7 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
5022
5123
|
dispatchOps(currentBatch.ops);
|
|
5023
5124
|
}
|
|
5024
5125
|
notify(currentBatch.updates, doNotBatchUpdates);
|
|
5025
|
-
|
|
5126
|
+
flushNowOrSoon();
|
|
5026
5127
|
}
|
|
5027
5128
|
});
|
|
5028
5129
|
return returnValue;
|
|
@@ -5038,13 +5139,11 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
5038
5139
|
}
|
|
5039
5140
|
}
|
|
5040
5141
|
function getStorageStatus() {
|
|
5041
|
-
if (_getInitialStatePromise === null) {
|
|
5042
|
-
return "not-loaded";
|
|
5043
|
-
}
|
|
5044
5142
|
if (context.root === void 0) {
|
|
5045
|
-
return "loading";
|
|
5143
|
+
return _getStorage$ === null ? "not-loaded" : "loading";
|
|
5144
|
+
} else {
|
|
5145
|
+
return context.unacknowledgedOps.size === 0 ? "synchronized" : "synchronizing";
|
|
5046
5146
|
}
|
|
5047
|
-
return context.unacknowledgedOps.size === 0 ? "synchronized" : "synchronizing";
|
|
5048
5147
|
}
|
|
5049
5148
|
let _lastStorageStatus = getStorageStatus();
|
|
5050
5149
|
function notifyStorageStatus() {
|
|
@@ -5059,15 +5158,20 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
5059
5158
|
(others) => others.map((other, index) => userToTreeNode(`Other ${index}`, other))
|
|
5060
5159
|
);
|
|
5061
5160
|
const events = {
|
|
5161
|
+
connection: eventHub.connection.observable,
|
|
5162
|
+
// Old/deprecated API
|
|
5163
|
+
status: eventHub.status.observable,
|
|
5164
|
+
// New/recommended API
|
|
5165
|
+
lostConnection: eventHub.lostConnection.observable,
|
|
5062
5166
|
customEvent: eventHub.customEvent.observable,
|
|
5063
5167
|
others: eventHub.others.observable,
|
|
5064
5168
|
me: eventHub.me.observable,
|
|
5065
5169
|
error: eventHub.error.observable,
|
|
5066
|
-
connection: eventHub.connection.observable,
|
|
5067
5170
|
storage: eventHub.storage.observable,
|
|
5068
5171
|
history: eventHub.history.observable,
|
|
5069
5172
|
storageDidLoad: eventHub.storageDidLoad.observable,
|
|
5070
|
-
storageStatus: eventHub.storageStatus.observable
|
|
5173
|
+
storageStatus: eventHub.storageStatus.observable,
|
|
5174
|
+
docUpdated: eventHub.docUpdated.observable
|
|
5071
5175
|
};
|
|
5072
5176
|
return {
|
|
5073
5177
|
/* NOTE: Exposing __internal here only to allow testing implementation details in unit tests */
|
|
@@ -5091,7 +5195,7 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
5091
5195
|
send: {
|
|
5092
5196
|
// These exist only for our E2E testing app
|
|
5093
5197
|
explicitClose: (event) => managedSocket._privateSendMachineEvent({ type: "EXPLICIT_SOCKET_CLOSE", event }),
|
|
5094
|
-
implicitClose: () => managedSocket._privateSendMachineEvent({ type: "
|
|
5198
|
+
implicitClose: () => managedSocket._privateSendMachineEvent({ type: "NAVIGATOR_OFFLINE" })
|
|
5095
5199
|
}
|
|
5096
5200
|
},
|
|
5097
5201
|
id: config.roomId,
|
|
@@ -5102,6 +5206,7 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
5102
5206
|
destroy: () => managedSocket.destroy(),
|
|
5103
5207
|
// Presence
|
|
5104
5208
|
updatePresence,
|
|
5209
|
+
updateDoc,
|
|
5105
5210
|
broadcastEvent,
|
|
5106
5211
|
// Storage
|
|
5107
5212
|
batch,
|
|
@@ -5113,13 +5218,15 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
5113
5218
|
pause: pauseHistory,
|
|
5114
5219
|
resume: resumeHistory
|
|
5115
5220
|
},
|
|
5221
|
+
getDoc,
|
|
5116
5222
|
getStorage,
|
|
5117
5223
|
getStorageSnapshot,
|
|
5118
5224
|
getStorageStatus,
|
|
5119
5225
|
events,
|
|
5120
5226
|
// Core
|
|
5121
|
-
|
|
5122
|
-
|
|
5227
|
+
getStatus: () => managedSocket.getStatus(),
|
|
5228
|
+
getConnectionState: () => managedSocket.getLegacyStatus(),
|
|
5229
|
+
isSelfAware: () => context.sessionInfo.current !== null,
|
|
5123
5230
|
getSelf: () => self.current,
|
|
5124
5231
|
// Presence
|
|
5125
5232
|
getPresence: () => context.me.current,
|
|
@@ -5171,6 +5278,12 @@ function makeClassicSubscribeFn(events) {
|
|
|
5171
5278
|
return events.connection.subscribe(
|
|
5172
5279
|
callback
|
|
5173
5280
|
);
|
|
5281
|
+
case "status":
|
|
5282
|
+
return events.status.subscribe(callback);
|
|
5283
|
+
case "lost-connection":
|
|
5284
|
+
return events.lostConnection.subscribe(
|
|
5285
|
+
callback
|
|
5286
|
+
);
|
|
5174
5287
|
case "history":
|
|
5175
5288
|
return events.history.subscribe(callback);
|
|
5176
5289
|
case "storage-status":
|
|
@@ -5204,7 +5317,7 @@ function makeClassicSubscribeFn(events) {
|
|
|
5204
5317
|
return subscribe;
|
|
5205
5318
|
}
|
|
5206
5319
|
function isRoomEventName(value) {
|
|
5207
|
-
return value === "my-presence" || value === "others" || value === "event" || value === "error" || value === "
|
|
5320
|
+
return value === "my-presence" || value === "others" || value === "event" || value === "error" || value === "history" || value === "status" || value === "storage-status" || value === "lost-connection" || value === "connection";
|
|
5208
5321
|
}
|
|
5209
5322
|
function makeCreateSocketDelegateForRoom(liveblocksServer, WebSocketPolyfill) {
|
|
5210
5323
|
return (richToken) => {
|
|
@@ -5221,7 +5334,7 @@ function makeCreateSocketDelegateForRoom(liveblocksServer, WebSocketPolyfill) {
|
|
|
5221
5334
|
// @ts-ignore (__PACKAGE_VERSION__ will be injected by the build script)
|
|
5222
5335
|
true ? (
|
|
5223
5336
|
/* istanbul ignore next */
|
|
5224
|
-
"1.1.0-
|
|
5337
|
+
"1.1.0-yjs1"
|
|
5225
5338
|
) : "dev"}`
|
|
5226
5339
|
);
|
|
5227
5340
|
};
|
|
@@ -5324,20 +5437,28 @@ function fetchAuthEndpoint(fetch2, endpoint, body) {
|
|
|
5324
5437
|
var MIN_THROTTLE = 16;
|
|
5325
5438
|
var MAX_THROTTLE = 1e3;
|
|
5326
5439
|
var DEFAULT_THROTTLE = 100;
|
|
5440
|
+
var MIN_LOST_CONNECTION_TIMEOUT = 200;
|
|
5441
|
+
var RECOMMENDED_MIN_LOST_CONNECTION_TIMEOUT = 1e3;
|
|
5442
|
+
var MAX_LOST_CONNECTION_TIMEOUT = 3e4;
|
|
5443
|
+
var DEFAULT_LOST_CONNECTION_TIMEOUT = 5e3;
|
|
5327
5444
|
function getServerFromClientOptions(clientOptions) {
|
|
5328
5445
|
const rawOptions = clientOptions;
|
|
5329
5446
|
return typeof rawOptions.liveblocksServer === "string" ? rawOptions.liveblocksServer : "wss://api.liveblocks.io/v6";
|
|
5330
5447
|
}
|
|
5331
5448
|
function createClient(options) {
|
|
5449
|
+
var _a, _b;
|
|
5332
5450
|
const clientOptions = options;
|
|
5333
|
-
const throttleDelay =
|
|
5451
|
+
const throttleDelay = getThrottle((_a = clientOptions.throttle) != null ? _a : DEFAULT_THROTTLE);
|
|
5452
|
+
const lostConnectionTimeout = getLostConnectionTimeout(
|
|
5453
|
+
(_b = clientOptions.lostConnectionTimeout) != null ? _b : DEFAULT_LOST_CONNECTION_TIMEOUT
|
|
5454
|
+
);
|
|
5334
5455
|
const rooms = /* @__PURE__ */ new Map();
|
|
5335
5456
|
function getRoom(roomId) {
|
|
5336
5457
|
const room = rooms.get(roomId);
|
|
5337
5458
|
return room ? room : null;
|
|
5338
5459
|
}
|
|
5339
5460
|
function enter(roomId, options2) {
|
|
5340
|
-
var
|
|
5461
|
+
var _a2, _b2, _c;
|
|
5341
5462
|
const existingRoom = rooms.get(roomId);
|
|
5342
5463
|
if (existingRoom !== void 0) {
|
|
5343
5464
|
return existingRoom;
|
|
@@ -5348,12 +5469,13 @@ function createClient(options) {
|
|
|
5348
5469
|
);
|
|
5349
5470
|
const newRoom = createRoom(
|
|
5350
5471
|
{
|
|
5351
|
-
initialPresence: (
|
|
5472
|
+
initialPresence: (_a2 = options2.initialPresence) != null ? _a2 : {},
|
|
5352
5473
|
initialStorage: options2.initialStorage
|
|
5353
5474
|
},
|
|
5354
5475
|
{
|
|
5355
5476
|
roomId,
|
|
5356
5477
|
throttleDelay,
|
|
5478
|
+
lostConnectionTimeout,
|
|
5357
5479
|
polyfills: clientOptions.polyfills,
|
|
5358
5480
|
delegates: clientOptions.mockedDelegates,
|
|
5359
5481
|
enableDebugLogging: clientOptions.enableDebugLogging,
|
|
@@ -5370,7 +5492,7 @@ function createClient(options) {
|
|
|
5370
5492
|
rooms.set(roomId, newRoom);
|
|
5371
5493
|
setupDevTools(() => Array.from(rooms.keys()));
|
|
5372
5494
|
linkDevTools(roomId, newRoom);
|
|
5373
|
-
const shouldConnect = (
|
|
5495
|
+
const shouldConnect = (_b2 = options2.shouldInitiallyConnect) != null ? _b2 : true;
|
|
5374
5496
|
if (shouldConnect) {
|
|
5375
5497
|
if (typeof atob === "undefined") {
|
|
5376
5498
|
if (((_c = clientOptions.polyfills) == null ? void 0 : _c.atob) === void 0) {
|
|
@@ -5398,16 +5520,25 @@ function createClient(options) {
|
|
|
5398
5520
|
leave
|
|
5399
5521
|
};
|
|
5400
5522
|
}
|
|
5401
|
-
function
|
|
5402
|
-
if (
|
|
5403
|
-
return DEFAULT_THROTTLE;
|
|
5404
|
-
}
|
|
5405
|
-
if (typeof options.throttle !== "number" || options.throttle < MIN_THROTTLE || options.throttle > MAX_THROTTLE) {
|
|
5523
|
+
function checkBounds(option, value, min, max, recommendedMin) {
|
|
5524
|
+
if (typeof value !== "number" || value < min || value > max) {
|
|
5406
5525
|
throw new Error(
|
|
5407
|
-
|
|
5526
|
+
`${option} should be a number between ${recommendedMin != null ? recommendedMin : min} and ${max}.`
|
|
5408
5527
|
);
|
|
5409
5528
|
}
|
|
5410
|
-
return
|
|
5529
|
+
return value;
|
|
5530
|
+
}
|
|
5531
|
+
function getThrottle(value) {
|
|
5532
|
+
return checkBounds("throttle", value, MIN_THROTTLE, MAX_THROTTLE);
|
|
5533
|
+
}
|
|
5534
|
+
function getLostConnectionTimeout(value) {
|
|
5535
|
+
return checkBounds(
|
|
5536
|
+
"lostConnectionTimeout",
|
|
5537
|
+
value,
|
|
5538
|
+
MIN_LOST_CONNECTION_TIMEOUT,
|
|
5539
|
+
MAX_LOST_CONNECTION_TIMEOUT,
|
|
5540
|
+
RECOMMENDED_MIN_LOST_CONNECTION_TIMEOUT
|
|
5541
|
+
);
|
|
5411
5542
|
}
|
|
5412
5543
|
function prepareAuthentication(clientOptions, roomId) {
|
|
5413
5544
|
const { publicApiKey, authEndpoint } = clientOptions;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liveblocks/core",
|
|
3
|
-
"version": "1.1.0-
|
|
3
|
+
"version": "1.1.0-yjs1",
|
|
4
4
|
"description": "Shared code and foundational internals for Liveblocks",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"scripts": {
|
|
21
21
|
"dev": "tsup --watch",
|
|
22
22
|
"build": "tsup",
|
|
23
|
-
"format": "eslint --fix src
|
|
23
|
+
"format": "(eslint --fix src/ || true) && prettier --write src/",
|
|
24
24
|
"lint": "eslint src/",
|
|
25
25
|
"test": "jest --silent --verbose --color=always",
|
|
26
26
|
"test:types": "tsd",
|