@liveblocks/client 0.16.0 → 0.16.3
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/{lib/esm → esm}/index.js +84 -38
- package/{lib/esm → esm}/index.mjs +84 -38
- package/{lib/esm → esm}/internal.js +0 -0
- package/{lib/esm → esm}/internal.mjs +0 -0
- package/{lib/index.d.ts → index.d.ts} +19 -2
- package/{lib/index.js → index.js} +97 -38
- package/{lib/internal.d.ts → internal.d.ts} +82 -4
- package/{lib/internal.js → internal.js} +0 -0
- package/package.json +13 -13
package/{lib/esm → esm}/index.js
RENAMED
|
@@ -915,6 +915,20 @@ class LiveMap extends AbstractCrdt {
|
|
|
915
915
|
}
|
|
916
916
|
}
|
|
917
917
|
|
|
918
|
+
function parseJson(rawMessage) {
|
|
919
|
+
try {
|
|
920
|
+
return JSON.parse(rawMessage);
|
|
921
|
+
} catch (e) {
|
|
922
|
+
return void 0;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
function isJsonArray(data) {
|
|
926
|
+
return Array.isArray(data);
|
|
927
|
+
}
|
|
928
|
+
function isJsonObject(data) {
|
|
929
|
+
return data !== null && typeof data === "object" && !isJsonArray(data);
|
|
930
|
+
}
|
|
931
|
+
|
|
918
932
|
var __defProp$2 = Object.defineProperty;
|
|
919
933
|
var __defProps$2 = Object.defineProperties;
|
|
920
934
|
var __getOwnPropDescs$2 = Object.getOwnPropertyDescriptors;
|
|
@@ -942,6 +956,9 @@ function remove(array, item) {
|
|
|
942
956
|
}
|
|
943
957
|
}
|
|
944
958
|
}
|
|
959
|
+
function compact(items) {
|
|
960
|
+
return items.filter((item) => item != null);
|
|
961
|
+
}
|
|
945
962
|
function creationOpToLiveStructure(op) {
|
|
946
963
|
switch (op.type) {
|
|
947
964
|
case OpType.CreateRegister:
|
|
@@ -1151,15 +1168,12 @@ function findNonSerializableValue(value, path = "") {
|
|
|
1151
1168
|
return false;
|
|
1152
1169
|
}
|
|
1153
1170
|
function isTokenValid(token) {
|
|
1154
|
-
if (token === null) {
|
|
1155
|
-
return false;
|
|
1156
|
-
}
|
|
1157
1171
|
const tokenParts = token.split(".");
|
|
1158
1172
|
if (tokenParts.length !== 3) {
|
|
1159
1173
|
return false;
|
|
1160
1174
|
}
|
|
1161
|
-
const data =
|
|
1162
|
-
if (typeof data.exp !== "number") {
|
|
1175
|
+
const data = parseJson(atob(tokenParts[1]));
|
|
1176
|
+
if (data === void 0 || !isJsonObject(data) || typeof data.exp !== "number") {
|
|
1163
1177
|
return false;
|
|
1164
1178
|
}
|
|
1165
1179
|
const now = Date.now();
|
|
@@ -1621,19 +1635,20 @@ function makeOthers(userMap) {
|
|
|
1621
1635
|
function makeStateMachine(state, context, mockedEffects) {
|
|
1622
1636
|
const effects = mockedEffects || {
|
|
1623
1637
|
authenticate(auth, createWebSocket) {
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
const
|
|
1638
|
+
const token = state.token;
|
|
1639
|
+
if (token && isTokenValid(token)) {
|
|
1640
|
+
const parsedToken = parseToken(token);
|
|
1641
|
+
const socket = createWebSocket(token);
|
|
1627
1642
|
authenticationSuccess(parsedToken, socket);
|
|
1628
1643
|
} else {
|
|
1629
|
-
return auth(context.
|
|
1644
|
+
return auth(context.roomId).then(({ token: token2 }) => {
|
|
1630
1645
|
if (state.connection.state !== "authenticating") {
|
|
1631
1646
|
return;
|
|
1632
1647
|
}
|
|
1633
|
-
const parsedToken = parseToken(
|
|
1634
|
-
const socket = createWebSocket(
|
|
1648
|
+
const parsedToken = parseToken(token2);
|
|
1649
|
+
const socket = createWebSocket(token2);
|
|
1635
1650
|
authenticationSuccess(parsedToken, socket);
|
|
1636
|
-
state.token =
|
|
1651
|
+
state.token = token2;
|
|
1637
1652
|
}).catch((er) => authenticationFailure(er));
|
|
1638
1653
|
}
|
|
1639
1654
|
},
|
|
@@ -1733,7 +1748,7 @@ function makeStateMachine(state, context, mockedEffects) {
|
|
|
1733
1748
|
generateId,
|
|
1734
1749
|
generateOpId,
|
|
1735
1750
|
dispatch: storageDispatch,
|
|
1736
|
-
roomId: context.
|
|
1751
|
+
roomId: context.roomId
|
|
1737
1752
|
});
|
|
1738
1753
|
}
|
|
1739
1754
|
function addItem(id, item) {
|
|
@@ -1808,6 +1823,7 @@ function makeStateMachine(state, context, mockedEffects) {
|
|
|
1808
1823
|
return `${getConnectionId()}:${state.opClock++}`;
|
|
1809
1824
|
}
|
|
1810
1825
|
function apply(item, isLocal) {
|
|
1826
|
+
var _a;
|
|
1811
1827
|
const result = {
|
|
1812
1828
|
reverse: [],
|
|
1813
1829
|
updates: {
|
|
@@ -1815,6 +1831,7 @@ function makeStateMachine(state, context, mockedEffects) {
|
|
|
1815
1831
|
presence: false
|
|
1816
1832
|
}
|
|
1817
1833
|
};
|
|
1834
|
+
const createdNodeIds = /* @__PURE__ */ new Set();
|
|
1818
1835
|
for (const op of item) {
|
|
1819
1836
|
if (op.type === "presence") {
|
|
1820
1837
|
const reverse = {
|
|
@@ -1829,7 +1846,7 @@ function makeStateMachine(state, context, mockedEffects) {
|
|
|
1829
1846
|
state.buffer.presence = op.data;
|
|
1830
1847
|
} else {
|
|
1831
1848
|
for (const key in op.data) {
|
|
1832
|
-
state.buffer.presence[key] = op.data;
|
|
1849
|
+
state.buffer.presence[key] = op.data[key];
|
|
1833
1850
|
}
|
|
1834
1851
|
}
|
|
1835
1852
|
result.reverse.unshift(reverse);
|
|
@@ -1840,8 +1857,14 @@ function makeStateMachine(state, context, mockedEffects) {
|
|
|
1840
1857
|
}
|
|
1841
1858
|
const applyOpResult = applyOp(op, isLocal);
|
|
1842
1859
|
if (applyOpResult.modified) {
|
|
1843
|
-
|
|
1844
|
-
|
|
1860
|
+
const parentId = (_a = applyOpResult.modified.node._parent) == null ? void 0 : _a._id;
|
|
1861
|
+
if (!createdNodeIds.has(parentId)) {
|
|
1862
|
+
result.updates.storageUpdates.set(applyOpResult.modified.node._id, mergeStorageUpdates(result.updates.storageUpdates.get(applyOpResult.modified.node._id), applyOpResult.modified));
|
|
1863
|
+
result.reverse.unshift(...applyOpResult.reverse);
|
|
1864
|
+
}
|
|
1865
|
+
if (op.type === OpType.CreateList || op.type === OpType.CreateMap || op.type === OpType.CreateObject) {
|
|
1866
|
+
createdNodeIds.add(applyOpResult.modified.node._id);
|
|
1867
|
+
}
|
|
1845
1868
|
}
|
|
1846
1869
|
}
|
|
1847
1870
|
}
|
|
@@ -2061,59 +2084,72 @@ See v0.13 release notes for more information.
|
|
|
2061
2084
|
}
|
|
2062
2085
|
return { type: "enter", user: state.users[message.actor] };
|
|
2063
2086
|
}
|
|
2087
|
+
function parseServerMessage(data) {
|
|
2088
|
+
if (!isJsonObject(data)) {
|
|
2089
|
+
return null;
|
|
2090
|
+
}
|
|
2091
|
+
return data;
|
|
2092
|
+
}
|
|
2093
|
+
function parseServerMessages(text) {
|
|
2094
|
+
const data = parseJson(text);
|
|
2095
|
+
if (data === void 0) {
|
|
2096
|
+
return null;
|
|
2097
|
+
} else if (isJsonArray(data)) {
|
|
2098
|
+
return compact(data.map((item) => parseServerMessage(item)));
|
|
2099
|
+
} else {
|
|
2100
|
+
return compact([parseServerMessage(data)]);
|
|
2101
|
+
}
|
|
2102
|
+
}
|
|
2064
2103
|
function onMessage(event) {
|
|
2065
2104
|
if (event.data === "pong") {
|
|
2066
2105
|
clearTimeout(state.timeoutHandles.pongTimeout);
|
|
2067
2106
|
return;
|
|
2068
2107
|
}
|
|
2069
|
-
const
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
subMessages = message;
|
|
2073
|
-
} else {
|
|
2074
|
-
subMessages.push(message);
|
|
2108
|
+
const messages = parseServerMessages(event.data);
|
|
2109
|
+
if (messages === null || messages.length === 0) {
|
|
2110
|
+
return;
|
|
2075
2111
|
}
|
|
2076
2112
|
const updates = {
|
|
2077
2113
|
storageUpdates: /* @__PURE__ */ new Map(),
|
|
2078
2114
|
others: []
|
|
2079
2115
|
};
|
|
2080
|
-
for (const
|
|
2081
|
-
switch (
|
|
2116
|
+
for (const message of messages) {
|
|
2117
|
+
switch (message.type) {
|
|
2082
2118
|
case ServerMessageType.UserJoined: {
|
|
2083
2119
|
updates.others.push(onUserJoinedMessage(message));
|
|
2084
2120
|
break;
|
|
2085
2121
|
}
|
|
2086
2122
|
case ServerMessageType.UpdatePresence: {
|
|
2087
|
-
const othersPresenceUpdate = onUpdatePresenceMessage(
|
|
2123
|
+
const othersPresenceUpdate = onUpdatePresenceMessage(message);
|
|
2088
2124
|
if (othersPresenceUpdate) {
|
|
2089
2125
|
updates.others.push(othersPresenceUpdate);
|
|
2090
2126
|
}
|
|
2091
2127
|
break;
|
|
2092
2128
|
}
|
|
2093
2129
|
case ServerMessageType.Event: {
|
|
2094
|
-
onEvent(
|
|
2130
|
+
onEvent(message);
|
|
2095
2131
|
break;
|
|
2096
2132
|
}
|
|
2097
2133
|
case ServerMessageType.UserLeft: {
|
|
2098
|
-
const event2 = onUserLeftMessage(
|
|
2134
|
+
const event2 = onUserLeftMessage(message);
|
|
2099
2135
|
if (event2) {
|
|
2100
2136
|
updates.others.push(event2);
|
|
2101
2137
|
}
|
|
2102
2138
|
break;
|
|
2103
2139
|
}
|
|
2104
2140
|
case ServerMessageType.RoomState: {
|
|
2105
|
-
updates.others.push(onRoomStateMessage(
|
|
2141
|
+
updates.others.push(onRoomStateMessage(message));
|
|
2106
2142
|
break;
|
|
2107
2143
|
}
|
|
2108
2144
|
case ServerMessageType.InitialStorageState: {
|
|
2109
2145
|
const offlineOps = new Map(state.offlineOperations);
|
|
2110
|
-
createOrUpdateRootFromMessage(
|
|
2146
|
+
createOrUpdateRootFromMessage(message);
|
|
2111
2147
|
applyAndSendOfflineOps(offlineOps);
|
|
2112
2148
|
_getInitialStateResolver == null ? void 0 : _getInitialStateResolver();
|
|
2113
2149
|
break;
|
|
2114
2150
|
}
|
|
2115
2151
|
case ServerMessageType.UpdateStorage: {
|
|
2116
|
-
const applyResult = apply(
|
|
2152
|
+
const applyResult = apply(message.ops, false);
|
|
2117
2153
|
applyResult.updates.storageUpdates.forEach((value, key) => {
|
|
2118
2154
|
updates.storageUpdates.set(key, mergeStorageUpdates(updates.storageUpdates.get(key), value));
|
|
2119
2155
|
});
|
|
@@ -2531,7 +2567,7 @@ function createRoom(options, context) {
|
|
|
2531
2567
|
const state = defaultState(options.defaultPresence, options.defaultStorageRoot);
|
|
2532
2568
|
const machine = makeStateMachine(state, context);
|
|
2533
2569
|
const room = {
|
|
2534
|
-
id: context.
|
|
2570
|
+
id: context.roomId,
|
|
2535
2571
|
getConnectionState: machine.selectors.getConnectionState,
|
|
2536
2572
|
getSelf: machine.selectors.getSelf,
|
|
2537
2573
|
subscribe: machine.subscribe,
|
|
@@ -2572,11 +2608,15 @@ function parseToken(token) {
|
|
|
2572
2608
|
if (tokenParts.length !== 3) {
|
|
2573
2609
|
throw new Error(`Authentication error. Liveblocks could not parse the response of your authentication endpoint`);
|
|
2574
2610
|
}
|
|
2575
|
-
const data =
|
|
2576
|
-
if (typeof data.actor
|
|
2577
|
-
|
|
2611
|
+
const data = parseJson(atob(tokenParts[1]));
|
|
2612
|
+
if (data !== void 0 && isJsonObject(data) && typeof data.actor === "number" && (data.id === void 0 || typeof data.id === "string")) {
|
|
2613
|
+
return {
|
|
2614
|
+
actor: data.actor,
|
|
2615
|
+
id: data.id,
|
|
2616
|
+
info: data.info
|
|
2617
|
+
};
|
|
2578
2618
|
}
|
|
2579
|
-
|
|
2619
|
+
throw new Error(`Authentication error. Liveblocks could not parse the response of your authentication endpoint`);
|
|
2580
2620
|
}
|
|
2581
2621
|
function prepareCreateWebSocket(liveblocksServer, WebSocketPolyfill) {
|
|
2582
2622
|
if (typeof window === "undefined" && WebSocketPolyfill == null) {
|
|
@@ -2654,7 +2694,7 @@ function createClient(options) {
|
|
|
2654
2694
|
defaultPresence: options2.defaultPresence,
|
|
2655
2695
|
defaultStorageRoot: options2.defaultStorageRoot
|
|
2656
2696
|
}, {
|
|
2657
|
-
|
|
2697
|
+
roomId,
|
|
2658
2698
|
throttleDelay,
|
|
2659
2699
|
WebSocketPolyfill: clientOptions.WebSocketPolyfill,
|
|
2660
2700
|
fetchPolyfill: clientOptions.fetchPolyfill,
|
|
@@ -2746,7 +2786,10 @@ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
|
2746
2786
|
function lsonObjectToJson(obj) {
|
|
2747
2787
|
const result = {};
|
|
2748
2788
|
for (const key in obj) {
|
|
2749
|
-
|
|
2789
|
+
const val = obj[key];
|
|
2790
|
+
if (val !== void 0) {
|
|
2791
|
+
result[key] = lsonToJson(val);
|
|
2792
|
+
}
|
|
2750
2793
|
}
|
|
2751
2794
|
return result;
|
|
2752
2795
|
}
|
|
@@ -2936,7 +2979,10 @@ function patchImmutableNode(state, path, update) {
|
|
|
2936
2979
|
const newState = Object.assign({}, state);
|
|
2937
2980
|
for (const key in update.updates) {
|
|
2938
2981
|
if (((_a = update.updates[key]) == null ? void 0 : _a.type) === "update") {
|
|
2939
|
-
|
|
2982
|
+
const val = update.node.get(key);
|
|
2983
|
+
if (val !== void 0) {
|
|
2984
|
+
newState[key] = lsonToJson(val);
|
|
2985
|
+
}
|
|
2940
2986
|
} else if (((_b = update.updates[key]) == null ? void 0 : _b.type) === "delete") {
|
|
2941
2987
|
delete newState[key];
|
|
2942
2988
|
}
|
|
@@ -915,6 +915,20 @@ class LiveMap extends AbstractCrdt {
|
|
|
915
915
|
}
|
|
916
916
|
}
|
|
917
917
|
|
|
918
|
+
function parseJson(rawMessage) {
|
|
919
|
+
try {
|
|
920
|
+
return JSON.parse(rawMessage);
|
|
921
|
+
} catch (e) {
|
|
922
|
+
return void 0;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
function isJsonArray(data) {
|
|
926
|
+
return Array.isArray(data);
|
|
927
|
+
}
|
|
928
|
+
function isJsonObject(data) {
|
|
929
|
+
return data !== null && typeof data === "object" && !isJsonArray(data);
|
|
930
|
+
}
|
|
931
|
+
|
|
918
932
|
var __defProp$2 = Object.defineProperty;
|
|
919
933
|
var __defProps$2 = Object.defineProperties;
|
|
920
934
|
var __getOwnPropDescs$2 = Object.getOwnPropertyDescriptors;
|
|
@@ -942,6 +956,9 @@ function remove(array, item) {
|
|
|
942
956
|
}
|
|
943
957
|
}
|
|
944
958
|
}
|
|
959
|
+
function compact(items) {
|
|
960
|
+
return items.filter((item) => item != null);
|
|
961
|
+
}
|
|
945
962
|
function creationOpToLiveStructure(op) {
|
|
946
963
|
switch (op.type) {
|
|
947
964
|
case OpType.CreateRegister:
|
|
@@ -1151,15 +1168,12 @@ function findNonSerializableValue(value, path = "") {
|
|
|
1151
1168
|
return false;
|
|
1152
1169
|
}
|
|
1153
1170
|
function isTokenValid(token) {
|
|
1154
|
-
if (token === null) {
|
|
1155
|
-
return false;
|
|
1156
|
-
}
|
|
1157
1171
|
const tokenParts = token.split(".");
|
|
1158
1172
|
if (tokenParts.length !== 3) {
|
|
1159
1173
|
return false;
|
|
1160
1174
|
}
|
|
1161
|
-
const data =
|
|
1162
|
-
if (typeof data.exp !== "number") {
|
|
1175
|
+
const data = parseJson(atob(tokenParts[1]));
|
|
1176
|
+
if (data === void 0 || !isJsonObject(data) || typeof data.exp !== "number") {
|
|
1163
1177
|
return false;
|
|
1164
1178
|
}
|
|
1165
1179
|
const now = Date.now();
|
|
@@ -1621,19 +1635,20 @@ function makeOthers(userMap) {
|
|
|
1621
1635
|
function makeStateMachine(state, context, mockedEffects) {
|
|
1622
1636
|
const effects = mockedEffects || {
|
|
1623
1637
|
authenticate(auth, createWebSocket) {
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
const
|
|
1638
|
+
const token = state.token;
|
|
1639
|
+
if (token && isTokenValid(token)) {
|
|
1640
|
+
const parsedToken = parseToken(token);
|
|
1641
|
+
const socket = createWebSocket(token);
|
|
1627
1642
|
authenticationSuccess(parsedToken, socket);
|
|
1628
1643
|
} else {
|
|
1629
|
-
return auth(context.
|
|
1644
|
+
return auth(context.roomId).then(({ token: token2 }) => {
|
|
1630
1645
|
if (state.connection.state !== "authenticating") {
|
|
1631
1646
|
return;
|
|
1632
1647
|
}
|
|
1633
|
-
const parsedToken = parseToken(
|
|
1634
|
-
const socket = createWebSocket(
|
|
1648
|
+
const parsedToken = parseToken(token2);
|
|
1649
|
+
const socket = createWebSocket(token2);
|
|
1635
1650
|
authenticationSuccess(parsedToken, socket);
|
|
1636
|
-
state.token =
|
|
1651
|
+
state.token = token2;
|
|
1637
1652
|
}).catch((er) => authenticationFailure(er));
|
|
1638
1653
|
}
|
|
1639
1654
|
},
|
|
@@ -1733,7 +1748,7 @@ function makeStateMachine(state, context, mockedEffects) {
|
|
|
1733
1748
|
generateId,
|
|
1734
1749
|
generateOpId,
|
|
1735
1750
|
dispatch: storageDispatch,
|
|
1736
|
-
roomId: context.
|
|
1751
|
+
roomId: context.roomId
|
|
1737
1752
|
});
|
|
1738
1753
|
}
|
|
1739
1754
|
function addItem(id, item) {
|
|
@@ -1808,6 +1823,7 @@ function makeStateMachine(state, context, mockedEffects) {
|
|
|
1808
1823
|
return `${getConnectionId()}:${state.opClock++}`;
|
|
1809
1824
|
}
|
|
1810
1825
|
function apply(item, isLocal) {
|
|
1826
|
+
var _a;
|
|
1811
1827
|
const result = {
|
|
1812
1828
|
reverse: [],
|
|
1813
1829
|
updates: {
|
|
@@ -1815,6 +1831,7 @@ function makeStateMachine(state, context, mockedEffects) {
|
|
|
1815
1831
|
presence: false
|
|
1816
1832
|
}
|
|
1817
1833
|
};
|
|
1834
|
+
const createdNodeIds = /* @__PURE__ */ new Set();
|
|
1818
1835
|
for (const op of item) {
|
|
1819
1836
|
if (op.type === "presence") {
|
|
1820
1837
|
const reverse = {
|
|
@@ -1829,7 +1846,7 @@ function makeStateMachine(state, context, mockedEffects) {
|
|
|
1829
1846
|
state.buffer.presence = op.data;
|
|
1830
1847
|
} else {
|
|
1831
1848
|
for (const key in op.data) {
|
|
1832
|
-
state.buffer.presence[key] = op.data;
|
|
1849
|
+
state.buffer.presence[key] = op.data[key];
|
|
1833
1850
|
}
|
|
1834
1851
|
}
|
|
1835
1852
|
result.reverse.unshift(reverse);
|
|
@@ -1840,8 +1857,14 @@ function makeStateMachine(state, context, mockedEffects) {
|
|
|
1840
1857
|
}
|
|
1841
1858
|
const applyOpResult = applyOp(op, isLocal);
|
|
1842
1859
|
if (applyOpResult.modified) {
|
|
1843
|
-
|
|
1844
|
-
|
|
1860
|
+
const parentId = (_a = applyOpResult.modified.node._parent) == null ? void 0 : _a._id;
|
|
1861
|
+
if (!createdNodeIds.has(parentId)) {
|
|
1862
|
+
result.updates.storageUpdates.set(applyOpResult.modified.node._id, mergeStorageUpdates(result.updates.storageUpdates.get(applyOpResult.modified.node._id), applyOpResult.modified));
|
|
1863
|
+
result.reverse.unshift(...applyOpResult.reverse);
|
|
1864
|
+
}
|
|
1865
|
+
if (op.type === OpType.CreateList || op.type === OpType.CreateMap || op.type === OpType.CreateObject) {
|
|
1866
|
+
createdNodeIds.add(applyOpResult.modified.node._id);
|
|
1867
|
+
}
|
|
1845
1868
|
}
|
|
1846
1869
|
}
|
|
1847
1870
|
}
|
|
@@ -2061,59 +2084,72 @@ See v0.13 release notes for more information.
|
|
|
2061
2084
|
}
|
|
2062
2085
|
return { type: "enter", user: state.users[message.actor] };
|
|
2063
2086
|
}
|
|
2087
|
+
function parseServerMessage(data) {
|
|
2088
|
+
if (!isJsonObject(data)) {
|
|
2089
|
+
return null;
|
|
2090
|
+
}
|
|
2091
|
+
return data;
|
|
2092
|
+
}
|
|
2093
|
+
function parseServerMessages(text) {
|
|
2094
|
+
const data = parseJson(text);
|
|
2095
|
+
if (data === void 0) {
|
|
2096
|
+
return null;
|
|
2097
|
+
} else if (isJsonArray(data)) {
|
|
2098
|
+
return compact(data.map((item) => parseServerMessage(item)));
|
|
2099
|
+
} else {
|
|
2100
|
+
return compact([parseServerMessage(data)]);
|
|
2101
|
+
}
|
|
2102
|
+
}
|
|
2064
2103
|
function onMessage(event) {
|
|
2065
2104
|
if (event.data === "pong") {
|
|
2066
2105
|
clearTimeout(state.timeoutHandles.pongTimeout);
|
|
2067
2106
|
return;
|
|
2068
2107
|
}
|
|
2069
|
-
const
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
subMessages = message;
|
|
2073
|
-
} else {
|
|
2074
|
-
subMessages.push(message);
|
|
2108
|
+
const messages = parseServerMessages(event.data);
|
|
2109
|
+
if (messages === null || messages.length === 0) {
|
|
2110
|
+
return;
|
|
2075
2111
|
}
|
|
2076
2112
|
const updates = {
|
|
2077
2113
|
storageUpdates: /* @__PURE__ */ new Map(),
|
|
2078
2114
|
others: []
|
|
2079
2115
|
};
|
|
2080
|
-
for (const
|
|
2081
|
-
switch (
|
|
2116
|
+
for (const message of messages) {
|
|
2117
|
+
switch (message.type) {
|
|
2082
2118
|
case ServerMessageType.UserJoined: {
|
|
2083
2119
|
updates.others.push(onUserJoinedMessage(message));
|
|
2084
2120
|
break;
|
|
2085
2121
|
}
|
|
2086
2122
|
case ServerMessageType.UpdatePresence: {
|
|
2087
|
-
const othersPresenceUpdate = onUpdatePresenceMessage(
|
|
2123
|
+
const othersPresenceUpdate = onUpdatePresenceMessage(message);
|
|
2088
2124
|
if (othersPresenceUpdate) {
|
|
2089
2125
|
updates.others.push(othersPresenceUpdate);
|
|
2090
2126
|
}
|
|
2091
2127
|
break;
|
|
2092
2128
|
}
|
|
2093
2129
|
case ServerMessageType.Event: {
|
|
2094
|
-
onEvent(
|
|
2130
|
+
onEvent(message);
|
|
2095
2131
|
break;
|
|
2096
2132
|
}
|
|
2097
2133
|
case ServerMessageType.UserLeft: {
|
|
2098
|
-
const event2 = onUserLeftMessage(
|
|
2134
|
+
const event2 = onUserLeftMessage(message);
|
|
2099
2135
|
if (event2) {
|
|
2100
2136
|
updates.others.push(event2);
|
|
2101
2137
|
}
|
|
2102
2138
|
break;
|
|
2103
2139
|
}
|
|
2104
2140
|
case ServerMessageType.RoomState: {
|
|
2105
|
-
updates.others.push(onRoomStateMessage(
|
|
2141
|
+
updates.others.push(onRoomStateMessage(message));
|
|
2106
2142
|
break;
|
|
2107
2143
|
}
|
|
2108
2144
|
case ServerMessageType.InitialStorageState: {
|
|
2109
2145
|
const offlineOps = new Map(state.offlineOperations);
|
|
2110
|
-
createOrUpdateRootFromMessage(
|
|
2146
|
+
createOrUpdateRootFromMessage(message);
|
|
2111
2147
|
applyAndSendOfflineOps(offlineOps);
|
|
2112
2148
|
_getInitialStateResolver == null ? void 0 : _getInitialStateResolver();
|
|
2113
2149
|
break;
|
|
2114
2150
|
}
|
|
2115
2151
|
case ServerMessageType.UpdateStorage: {
|
|
2116
|
-
const applyResult = apply(
|
|
2152
|
+
const applyResult = apply(message.ops, false);
|
|
2117
2153
|
applyResult.updates.storageUpdates.forEach((value, key) => {
|
|
2118
2154
|
updates.storageUpdates.set(key, mergeStorageUpdates(updates.storageUpdates.get(key), value));
|
|
2119
2155
|
});
|
|
@@ -2531,7 +2567,7 @@ function createRoom(options, context) {
|
|
|
2531
2567
|
const state = defaultState(options.defaultPresence, options.defaultStorageRoot);
|
|
2532
2568
|
const machine = makeStateMachine(state, context);
|
|
2533
2569
|
const room = {
|
|
2534
|
-
id: context.
|
|
2570
|
+
id: context.roomId,
|
|
2535
2571
|
getConnectionState: machine.selectors.getConnectionState,
|
|
2536
2572
|
getSelf: machine.selectors.getSelf,
|
|
2537
2573
|
subscribe: machine.subscribe,
|
|
@@ -2572,11 +2608,15 @@ function parseToken(token) {
|
|
|
2572
2608
|
if (tokenParts.length !== 3) {
|
|
2573
2609
|
throw new Error(`Authentication error. Liveblocks could not parse the response of your authentication endpoint`);
|
|
2574
2610
|
}
|
|
2575
|
-
const data =
|
|
2576
|
-
if (typeof data.actor
|
|
2577
|
-
|
|
2611
|
+
const data = parseJson(atob(tokenParts[1]));
|
|
2612
|
+
if (data !== void 0 && isJsonObject(data) && typeof data.actor === "number" && (data.id === void 0 || typeof data.id === "string")) {
|
|
2613
|
+
return {
|
|
2614
|
+
actor: data.actor,
|
|
2615
|
+
id: data.id,
|
|
2616
|
+
info: data.info
|
|
2617
|
+
};
|
|
2578
2618
|
}
|
|
2579
|
-
|
|
2619
|
+
throw new Error(`Authentication error. Liveblocks could not parse the response of your authentication endpoint`);
|
|
2580
2620
|
}
|
|
2581
2621
|
function prepareCreateWebSocket(liveblocksServer, WebSocketPolyfill) {
|
|
2582
2622
|
if (typeof window === "undefined" && WebSocketPolyfill == null) {
|
|
@@ -2654,7 +2694,7 @@ function createClient(options) {
|
|
|
2654
2694
|
defaultPresence: options2.defaultPresence,
|
|
2655
2695
|
defaultStorageRoot: options2.defaultStorageRoot
|
|
2656
2696
|
}, {
|
|
2657
|
-
|
|
2697
|
+
roomId,
|
|
2658
2698
|
throttleDelay,
|
|
2659
2699
|
WebSocketPolyfill: clientOptions.WebSocketPolyfill,
|
|
2660
2700
|
fetchPolyfill: clientOptions.fetchPolyfill,
|
|
@@ -2746,7 +2786,10 @@ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
|
2746
2786
|
function lsonObjectToJson(obj) {
|
|
2747
2787
|
const result = {};
|
|
2748
2788
|
for (const key in obj) {
|
|
2749
|
-
|
|
2789
|
+
const val = obj[key];
|
|
2790
|
+
if (val !== void 0) {
|
|
2791
|
+
result[key] = lsonToJson(val);
|
|
2792
|
+
}
|
|
2750
2793
|
}
|
|
2751
2794
|
return result;
|
|
2752
2795
|
}
|
|
@@ -2936,7 +2979,10 @@ function patchImmutableNode(state, path, update) {
|
|
|
2936
2979
|
const newState = Object.assign({}, state);
|
|
2937
2980
|
for (const key in update.updates) {
|
|
2938
2981
|
if (((_a = update.updates[key]) == null ? void 0 : _a.type) === "update") {
|
|
2939
|
-
|
|
2982
|
+
const val = update.node.get(key);
|
|
2983
|
+
if (val !== void 0) {
|
|
2984
|
+
newState[key] = lsonToJson(val);
|
|
2985
|
+
}
|
|
2940
2986
|
} else if (((_b = update.updates[key]) == null ? void 0 : _b.type) === "delete") {
|
|
2941
2987
|
delete newState[key];
|
|
2942
2988
|
}
|
|
File without changes
|
|
File without changes
|
|
@@ -12,7 +12,7 @@ declare type Json = JsonScalar | JsonArray | JsonObject;
|
|
|
12
12
|
declare type JsonScalar = string | number | boolean | null;
|
|
13
13
|
declare type JsonArray = Json[];
|
|
14
14
|
declare type JsonObject = {
|
|
15
|
-
[key: string]: Json;
|
|
15
|
+
[key: string]: Json | undefined;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
/**
|
|
@@ -83,7 +83,7 @@ declare type Lson = Json | LiveObject<LsonObject> | LiveList<Lson> | LiveMap<str
|
|
|
83
83
|
* value or a Live storage data structure (LiveMap, LiveList, etc.)
|
|
84
84
|
*/
|
|
85
85
|
declare type LsonObject = {
|
|
86
|
-
[key: string]: Lson;
|
|
86
|
+
[key: string]: Lson | undefined;
|
|
87
87
|
};
|
|
88
88
|
|
|
89
89
|
/**
|
|
@@ -201,6 +201,10 @@ declare type UpdateDelta = {
|
|
|
201
201
|
} | {
|
|
202
202
|
type: "delete";
|
|
203
203
|
};
|
|
204
|
+
/**
|
|
205
|
+
* A LiveMap notification that is sent in-client to any subscribers whenever
|
|
206
|
+
* one or more of the values inside the LiveMap instance have changed.
|
|
207
|
+
*/
|
|
204
208
|
declare type LiveMapUpdates<TKey extends string, TValue extends Lson> = {
|
|
205
209
|
type: "LiveMap";
|
|
206
210
|
node: LiveMap<TKey, TValue>;
|
|
@@ -213,6 +217,10 @@ declare type LiveObjectUpdateDelta<O extends {
|
|
|
213
217
|
}> = {
|
|
214
218
|
[K in keyof O]?: UpdateDelta | undefined;
|
|
215
219
|
};
|
|
220
|
+
/**
|
|
221
|
+
* A LiveObject notification that is sent in-client to any subscribers whenever
|
|
222
|
+
* one or more of the entries inside the LiveObject instance have changed.
|
|
223
|
+
*/
|
|
216
224
|
declare type LiveObjectUpdates<TData extends LsonObject> = {
|
|
217
225
|
type: "LiveObject";
|
|
218
226
|
node: LiveObject<TData>;
|
|
@@ -235,6 +243,10 @@ declare type LiveListUpdateDelta = {
|
|
|
235
243
|
item: any;
|
|
236
244
|
type: "set";
|
|
237
245
|
};
|
|
246
|
+
/**
|
|
247
|
+
* A LiveList notification that is sent in-client to any subscribers whenever
|
|
248
|
+
* one or more of the items inside the LiveList instance have changed.
|
|
249
|
+
*/
|
|
238
250
|
declare type LiveListUpdates<TItem extends Lson> = {
|
|
239
251
|
type: "LiveList";
|
|
240
252
|
node: LiveList<TItem>;
|
|
@@ -248,6 +260,11 @@ declare type BroadcastOptions = {
|
|
|
248
260
|
*/
|
|
249
261
|
shouldQueueEventIfNotReady: boolean;
|
|
250
262
|
};
|
|
263
|
+
/**
|
|
264
|
+
* The payload of notifications sent (in-client) when LiveStructures change.
|
|
265
|
+
* Messages of this kind are not originating from the network, but are 100%
|
|
266
|
+
* in-client.
|
|
267
|
+
*/
|
|
251
268
|
declare type StorageUpdate = LiveMapUpdates<string, Lson> | LiveObjectUpdates<LsonObject> | LiveListUpdates<Lson>;
|
|
252
269
|
declare type Client = {
|
|
253
270
|
/**
|
|
@@ -1535,6 +1535,20 @@ var LiveMap = function (_AbstractCrdt) {
|
|
|
1535
1535
|
return LiveMap;
|
|
1536
1536
|
}(AbstractCrdt);
|
|
1537
1537
|
|
|
1538
|
+
function parseJson(rawMessage) {
|
|
1539
|
+
try {
|
|
1540
|
+
return JSON.parse(rawMessage);
|
|
1541
|
+
} catch (e) {
|
|
1542
|
+
return undefined;
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
function isJsonArray(data) {
|
|
1546
|
+
return Array.isArray(data);
|
|
1547
|
+
}
|
|
1548
|
+
function isJsonObject(data) {
|
|
1549
|
+
return data !== null && typeof data === "object" && !isJsonArray(data);
|
|
1550
|
+
}
|
|
1551
|
+
|
|
1538
1552
|
function remove(array, item) {
|
|
1539
1553
|
for (var i = 0; i < array.length; i++) {
|
|
1540
1554
|
if (array[i] === item) {
|
|
@@ -1543,6 +1557,11 @@ function remove(array, item) {
|
|
|
1543
1557
|
}
|
|
1544
1558
|
}
|
|
1545
1559
|
}
|
|
1560
|
+
function compact(items) {
|
|
1561
|
+
return items.filter(function (item) {
|
|
1562
|
+
return item != null;
|
|
1563
|
+
});
|
|
1564
|
+
}
|
|
1546
1565
|
function creationOpToLiveStructure(op) {
|
|
1547
1566
|
switch (op.type) {
|
|
1548
1567
|
case OpType.CreateRegister:
|
|
@@ -1804,19 +1823,15 @@ function findNonSerializableValue(value, path) {
|
|
|
1804
1823
|
return false;
|
|
1805
1824
|
}
|
|
1806
1825
|
function isTokenValid(token) {
|
|
1807
|
-
if (token === null) {
|
|
1808
|
-
return false;
|
|
1809
|
-
}
|
|
1810
|
-
|
|
1811
1826
|
var tokenParts = token.split(".");
|
|
1812
1827
|
|
|
1813
1828
|
if (tokenParts.length !== 3) {
|
|
1814
1829
|
return false;
|
|
1815
1830
|
}
|
|
1816
1831
|
|
|
1817
|
-
var data =
|
|
1832
|
+
var data = parseJson(atob(tokenParts[1]));
|
|
1818
1833
|
|
|
1819
|
-
if (typeof data.exp !== "number") {
|
|
1834
|
+
if (data === undefined || !isJsonObject(data) || typeof data.exp !== "number") {
|
|
1820
1835
|
return false;
|
|
1821
1836
|
}
|
|
1822
1837
|
|
|
@@ -2461,12 +2476,14 @@ function makeOthers(userMap) {
|
|
|
2461
2476
|
function makeStateMachine(state, context, mockedEffects) {
|
|
2462
2477
|
var effects = mockedEffects || {
|
|
2463
2478
|
authenticate: function authenticate(auth, createWebSocket) {
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2479
|
+
var token = state.token;
|
|
2480
|
+
|
|
2481
|
+
if (token && isTokenValid(token)) {
|
|
2482
|
+
var parsedToken = parseToken(token);
|
|
2483
|
+
var socket = createWebSocket(token);
|
|
2467
2484
|
authenticationSuccess(parsedToken, socket);
|
|
2468
2485
|
} else {
|
|
2469
|
-
return auth(context.
|
|
2486
|
+
return auth(context.roomId).then(function (_ref2) {
|
|
2470
2487
|
var token = _ref2.token;
|
|
2471
2488
|
|
|
2472
2489
|
if (state.connection.state !== "authenticating") {
|
|
@@ -2604,7 +2621,7 @@ function makeStateMachine(state, context, mockedEffects) {
|
|
|
2604
2621
|
generateId: generateId,
|
|
2605
2622
|
generateOpId: generateOpId,
|
|
2606
2623
|
dispatch: storageDispatch,
|
|
2607
|
-
roomId: context.
|
|
2624
|
+
roomId: context.roomId
|
|
2608
2625
|
});
|
|
2609
2626
|
}
|
|
2610
2627
|
|
|
@@ -2719,6 +2736,7 @@ function makeStateMachine(state, context, mockedEffects) {
|
|
|
2719
2736
|
presence: false
|
|
2720
2737
|
}
|
|
2721
2738
|
};
|
|
2739
|
+
var createdNodeIds = new Set();
|
|
2722
2740
|
|
|
2723
2741
|
for (var _iterator7 = _createForOfIteratorHelperLoose(item), _step7; !(_step7 = _iterator7()).done;) {
|
|
2724
2742
|
var op = _step7.value;
|
|
@@ -2739,7 +2757,7 @@ function makeStateMachine(state, context, mockedEffects) {
|
|
|
2739
2757
|
state.buffer.presence = op.data;
|
|
2740
2758
|
} else {
|
|
2741
2759
|
for (var _key3 in op.data) {
|
|
2742
|
-
state.buffer.presence[_key3] = op.data;
|
|
2760
|
+
state.buffer.presence[_key3] = op.data[_key3];
|
|
2743
2761
|
}
|
|
2744
2762
|
}
|
|
2745
2763
|
|
|
@@ -2753,11 +2771,21 @@ function makeStateMachine(state, context, mockedEffects) {
|
|
|
2753
2771
|
var applyOpResult = applyOp(op, isLocal);
|
|
2754
2772
|
|
|
2755
2773
|
if (applyOpResult.modified) {
|
|
2756
|
-
var
|
|
2774
|
+
var _applyOpResult$modifi;
|
|
2775
|
+
|
|
2776
|
+
var parentId = (_applyOpResult$modifi = applyOpResult.modified.node._parent) == null ? void 0 : _applyOpResult$modifi._id;
|
|
2777
|
+
|
|
2778
|
+
if (!createdNodeIds.has(parentId)) {
|
|
2779
|
+
var _result$reverse;
|
|
2757
2780
|
|
|
2758
|
-
|
|
2781
|
+
result.updates.storageUpdates.set(applyOpResult.modified.node._id, mergeStorageUpdates(result.updates.storageUpdates.get(applyOpResult.modified.node._id), applyOpResult.modified));
|
|
2759
2782
|
|
|
2760
|
-
|
|
2783
|
+
(_result$reverse = result.reverse).unshift.apply(_result$reverse, applyOpResult.reverse);
|
|
2784
|
+
}
|
|
2785
|
+
|
|
2786
|
+
if (op.type === OpType.CreateList || op.type === OpType.CreateMap || op.type === OpType.CreateObject) {
|
|
2787
|
+
createdNodeIds.add(applyOpResult.modified.node._id);
|
|
2788
|
+
}
|
|
2761
2789
|
}
|
|
2762
2790
|
}
|
|
2763
2791
|
}
|
|
@@ -3066,19 +3094,38 @@ function makeStateMachine(state, context, mockedEffects) {
|
|
|
3066
3094
|
};
|
|
3067
3095
|
}
|
|
3068
3096
|
|
|
3097
|
+
function parseServerMessage(data) {
|
|
3098
|
+
if (!isJsonObject(data)) {
|
|
3099
|
+
return null;
|
|
3100
|
+
}
|
|
3101
|
+
|
|
3102
|
+
return data;
|
|
3103
|
+
}
|
|
3104
|
+
|
|
3105
|
+
function parseServerMessages(text) {
|
|
3106
|
+
var data = parseJson(text);
|
|
3107
|
+
|
|
3108
|
+
if (data === undefined) {
|
|
3109
|
+
return null;
|
|
3110
|
+
} else if (isJsonArray(data)) {
|
|
3111
|
+
return compact(data.map(function (item) {
|
|
3112
|
+
return parseServerMessage(item);
|
|
3113
|
+
}));
|
|
3114
|
+
} else {
|
|
3115
|
+
return compact([parseServerMessage(data)]);
|
|
3116
|
+
}
|
|
3117
|
+
}
|
|
3118
|
+
|
|
3069
3119
|
function onMessage(event) {
|
|
3070
3120
|
if (event.data === "pong") {
|
|
3071
3121
|
clearTimeout(state.timeoutHandles.pongTimeout);
|
|
3072
3122
|
return;
|
|
3073
3123
|
}
|
|
3074
3124
|
|
|
3075
|
-
var
|
|
3076
|
-
var subMessages = [];
|
|
3125
|
+
var messages = parseServerMessages(event.data);
|
|
3077
3126
|
|
|
3078
|
-
if (
|
|
3079
|
-
|
|
3080
|
-
} else {
|
|
3081
|
-
subMessages.push(message);
|
|
3127
|
+
if (messages === null || messages.length === 0) {
|
|
3128
|
+
return;
|
|
3082
3129
|
}
|
|
3083
3130
|
|
|
3084
3131
|
var updates = {
|
|
@@ -3086,10 +3133,10 @@ function makeStateMachine(state, context, mockedEffects) {
|
|
|
3086
3133
|
others: []
|
|
3087
3134
|
};
|
|
3088
3135
|
|
|
3089
|
-
for (var _iterator9 = _createForOfIteratorHelperLoose(
|
|
3090
|
-
var
|
|
3136
|
+
for (var _iterator9 = _createForOfIteratorHelperLoose(messages), _step9; !(_step9 = _iterator9()).done;) {
|
|
3137
|
+
var message = _step9.value;
|
|
3091
3138
|
|
|
3092
|
-
switch (
|
|
3139
|
+
switch (message.type) {
|
|
3093
3140
|
case ServerMessageType.UserJoined:
|
|
3094
3141
|
{
|
|
3095
3142
|
updates.others.push(onUserJoinedMessage(message));
|
|
@@ -3098,7 +3145,7 @@ function makeStateMachine(state, context, mockedEffects) {
|
|
|
3098
3145
|
|
|
3099
3146
|
case ServerMessageType.UpdatePresence:
|
|
3100
3147
|
{
|
|
3101
|
-
var othersPresenceUpdate = onUpdatePresenceMessage(
|
|
3148
|
+
var othersPresenceUpdate = onUpdatePresenceMessage(message);
|
|
3102
3149
|
|
|
3103
3150
|
if (othersPresenceUpdate) {
|
|
3104
3151
|
updates.others.push(othersPresenceUpdate);
|
|
@@ -3109,13 +3156,13 @@ function makeStateMachine(state, context, mockedEffects) {
|
|
|
3109
3156
|
|
|
3110
3157
|
case ServerMessageType.Event:
|
|
3111
3158
|
{
|
|
3112
|
-
onEvent(
|
|
3159
|
+
onEvent(message);
|
|
3113
3160
|
break;
|
|
3114
3161
|
}
|
|
3115
3162
|
|
|
3116
3163
|
case ServerMessageType.UserLeft:
|
|
3117
3164
|
{
|
|
3118
|
-
var _event = onUserLeftMessage(
|
|
3165
|
+
var _event = onUserLeftMessage(message);
|
|
3119
3166
|
|
|
3120
3167
|
if (_event) {
|
|
3121
3168
|
updates.others.push(_event);
|
|
@@ -3126,14 +3173,14 @@ function makeStateMachine(state, context, mockedEffects) {
|
|
|
3126
3173
|
|
|
3127
3174
|
case ServerMessageType.RoomState:
|
|
3128
3175
|
{
|
|
3129
|
-
updates.others.push(onRoomStateMessage(
|
|
3176
|
+
updates.others.push(onRoomStateMessage(message));
|
|
3130
3177
|
break;
|
|
3131
3178
|
}
|
|
3132
3179
|
|
|
3133
3180
|
case ServerMessageType.InitialStorageState:
|
|
3134
3181
|
{
|
|
3135
3182
|
var offlineOps = new Map(state.offlineOperations);
|
|
3136
|
-
createOrUpdateRootFromMessage(
|
|
3183
|
+
createOrUpdateRootFromMessage(message);
|
|
3137
3184
|
applyAndSendOfflineOps(offlineOps);
|
|
3138
3185
|
_getInitialStateResolver == null ? void 0 : _getInitialStateResolver();
|
|
3139
3186
|
break;
|
|
@@ -3141,7 +3188,7 @@ function makeStateMachine(state, context, mockedEffects) {
|
|
|
3141
3188
|
|
|
3142
3189
|
case ServerMessageType.UpdateStorage:
|
|
3143
3190
|
{
|
|
3144
|
-
var applyResult = apply(
|
|
3191
|
+
var applyResult = apply(message.ops, false);
|
|
3145
3192
|
applyResult.updates.storageUpdates.forEach(function (value, key) {
|
|
3146
3193
|
updates.storageUpdates.set(key, mergeStorageUpdates(updates.storageUpdates.get(key), value));
|
|
3147
3194
|
});
|
|
@@ -3701,7 +3748,7 @@ function createRoom(options, context) {
|
|
|
3701
3748
|
var state = defaultState(options.defaultPresence, options.defaultStorageRoot);
|
|
3702
3749
|
var machine = makeStateMachine(state, context);
|
|
3703
3750
|
var room = {
|
|
3704
|
-
id: context.
|
|
3751
|
+
id: context.roomId,
|
|
3705
3752
|
getConnectionState: machine.selectors.getConnectionState,
|
|
3706
3753
|
getSelf: machine.selectors.getSelf,
|
|
3707
3754
|
subscribe: machine.subscribe,
|
|
@@ -3753,13 +3800,17 @@ function parseToken(token) {
|
|
|
3753
3800
|
throw new Error("Authentication error. Liveblocks could not parse the response of your authentication endpoint");
|
|
3754
3801
|
}
|
|
3755
3802
|
|
|
3756
|
-
var data =
|
|
3803
|
+
var data = parseJson(atob(tokenParts[1]));
|
|
3757
3804
|
|
|
3758
|
-
if (typeof data.actor
|
|
3759
|
-
|
|
3805
|
+
if (data !== undefined && isJsonObject(data) && typeof data.actor === "number" && (data.id === undefined || typeof data.id === "string")) {
|
|
3806
|
+
return {
|
|
3807
|
+
actor: data.actor,
|
|
3808
|
+
id: data.id,
|
|
3809
|
+
info: data.info
|
|
3810
|
+
};
|
|
3760
3811
|
}
|
|
3761
3812
|
|
|
3762
|
-
|
|
3813
|
+
throw new Error("Authentication error. Liveblocks could not parse the response of your authentication endpoint");
|
|
3763
3814
|
}
|
|
3764
3815
|
|
|
3765
3816
|
function prepareCreateWebSocket(liveblocksServer, WebSocketPolyfill) {
|
|
@@ -3865,7 +3916,7 @@ function createClient(options) {
|
|
|
3865
3916
|
defaultPresence: options.defaultPresence,
|
|
3866
3917
|
defaultStorageRoot: options.defaultStorageRoot
|
|
3867
3918
|
}, {
|
|
3868
|
-
|
|
3919
|
+
roomId: roomId,
|
|
3869
3920
|
throttleDelay: throttleDelay,
|
|
3870
3921
|
WebSocketPolyfill: clientOptions.WebSocketPolyfill,
|
|
3871
3922
|
fetchPolyfill: clientOptions.fetchPolyfill,
|
|
@@ -3955,7 +4006,11 @@ function lsonObjectToJson(obj) {
|
|
|
3955
4006
|
var result = {};
|
|
3956
4007
|
|
|
3957
4008
|
for (var _key in obj) {
|
|
3958
|
-
|
|
4009
|
+
var val = obj[_key];
|
|
4010
|
+
|
|
4011
|
+
if (val !== undefined) {
|
|
4012
|
+
result[_key] = lsonToJson(val);
|
|
4013
|
+
}
|
|
3959
4014
|
}
|
|
3960
4015
|
|
|
3961
4016
|
return result;
|
|
@@ -4199,7 +4254,11 @@ function patchImmutableNode(state, path, update) {
|
|
|
4199
4254
|
var _update$updates$_key, _update$updates$_key2;
|
|
4200
4255
|
|
|
4201
4256
|
if (((_update$updates$_key = update.updates[_key6]) == null ? void 0 : _update$updates$_key.type) === "update") {
|
|
4202
|
-
|
|
4257
|
+
var val = update.node.get(_key6);
|
|
4258
|
+
|
|
4259
|
+
if (val !== undefined) {
|
|
4260
|
+
newState[_key6] = lsonToJson(val);
|
|
4261
|
+
}
|
|
4203
4262
|
} else if (((_update$updates$_key2 = update.updates[_key6]) == null ? void 0 : _update$updates$_key2.type) === "delete") {
|
|
4204
4263
|
delete newState[_key6];
|
|
4205
4264
|
}
|
|
@@ -12,11 +12,14 @@ declare type Json = JsonScalar | JsonArray | JsonObject;
|
|
|
12
12
|
declare type JsonScalar = string | number | boolean | null;
|
|
13
13
|
declare type JsonArray = Json[];
|
|
14
14
|
declare type JsonObject = {
|
|
15
|
-
[key: string]: Json;
|
|
15
|
+
[key: string]: Json | undefined;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
declare type Presence = Record<string, unknown>;
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Messages that can be sent from the server to the client.
|
|
22
|
+
*/
|
|
20
23
|
declare type ServerMessage = UpdatePresenceMessage | UserJoinMessage | UserLeftMessage | EventMessage | RoomStateMessage | InitialDocumentStateMessage | UpdateStorageMessage;
|
|
21
24
|
declare enum ServerMessageType {
|
|
22
25
|
UpdatePresence = 100,
|
|
@@ -27,45 +30,116 @@ declare enum ServerMessageType {
|
|
|
27
30
|
InitialStorageState = 200,
|
|
28
31
|
UpdateStorage = 201
|
|
29
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Sent by the WebSocket server to a single client in response to the client
|
|
35
|
+
* joining the Room, to provide the initial state of the Room. The payload
|
|
36
|
+
* includes a list of all other Users that already are in the Room.
|
|
37
|
+
*/
|
|
30
38
|
declare type RoomStateMessage = {
|
|
31
39
|
type: ServerMessageType.RoomState;
|
|
32
40
|
users: {
|
|
33
41
|
[actor: number]: {
|
|
34
42
|
id?: string;
|
|
35
|
-
info?:
|
|
43
|
+
info?: Json;
|
|
36
44
|
};
|
|
37
45
|
};
|
|
38
46
|
};
|
|
47
|
+
/**
|
|
48
|
+
* Sent by the WebSocket server and broadcasted to all clients to announce that
|
|
49
|
+
* a User updated their presence. For example, when a user moves their cursor.
|
|
50
|
+
*
|
|
51
|
+
* In most cases, the data payload will only include the fields from the
|
|
52
|
+
* Presence that have been changed since the last announcement. However, after
|
|
53
|
+
* a new user joins a room, a "full presence" will be announced so the newly
|
|
54
|
+
* connected user will get each other's user full presence at least once. In
|
|
55
|
+
* those cases, the `targetActor` field indicates the newly connected client,
|
|
56
|
+
* so all other existing clients can ignore this broadcasted message.
|
|
57
|
+
*/
|
|
39
58
|
declare type UpdatePresenceMessage = {
|
|
40
59
|
type: ServerMessageType.UpdatePresence;
|
|
60
|
+
/**
|
|
61
|
+
* The User whose Presence has changed.
|
|
62
|
+
*/
|
|
41
63
|
actor: number;
|
|
64
|
+
/**
|
|
65
|
+
* The partial or full Presence of a User. If the `targetActor` field is set,
|
|
66
|
+
* this will be the full Presence, otherwise it only contain the fields that
|
|
67
|
+
* have changed since the last broadcast.
|
|
68
|
+
*/
|
|
42
69
|
data: Presence;
|
|
70
|
+
/**
|
|
71
|
+
* If this message was sent in response to a newly joined user, this field
|
|
72
|
+
* indicates which client this message is for. Other existing clients may
|
|
73
|
+
* ignore this message if this message isn't targeted for them.
|
|
74
|
+
*/
|
|
43
75
|
targetActor?: number;
|
|
44
76
|
};
|
|
77
|
+
/**
|
|
78
|
+
* Sent by the WebSocket server and broadcasted to all clients to announce that
|
|
79
|
+
* a new User has joined the Room.
|
|
80
|
+
*/
|
|
45
81
|
declare type UserJoinMessage = {
|
|
46
82
|
type: ServerMessageType.UserJoined;
|
|
47
83
|
actor: number;
|
|
84
|
+
/**
|
|
85
|
+
* The id of the User that has been set in the authentication endpoint.
|
|
86
|
+
* Useful to get additional information about the connected user.
|
|
87
|
+
*/
|
|
48
88
|
id?: string;
|
|
49
|
-
|
|
89
|
+
/**
|
|
90
|
+
* Additional user information that has been set in the authentication
|
|
91
|
+
* endpoint.
|
|
92
|
+
*/
|
|
93
|
+
info?: Json;
|
|
50
94
|
};
|
|
95
|
+
/**
|
|
96
|
+
* Sent by the WebSocket server and broadcasted to all clients to announce that
|
|
97
|
+
* a new User has left the Room.
|
|
98
|
+
*/
|
|
51
99
|
declare type UserLeftMessage = {
|
|
52
100
|
type: ServerMessageType.UserLeft;
|
|
53
101
|
actor: number;
|
|
54
102
|
};
|
|
103
|
+
/**
|
|
104
|
+
* Sent by the WebSocket server and broadcasted to all clients to announce that
|
|
105
|
+
* a User broadcasted an Event to everyone in the Room.
|
|
106
|
+
*/
|
|
55
107
|
declare type EventMessage = {
|
|
56
108
|
type: ServerMessageType.Event;
|
|
109
|
+
/**
|
|
110
|
+
* The User who broadcasted the Event.
|
|
111
|
+
*/
|
|
57
112
|
actor: number;
|
|
113
|
+
/**
|
|
114
|
+
* The arbitrary payload of the Event. This can be any JSON value. Clients
|
|
115
|
+
* will have to manually verify/decode this event.
|
|
116
|
+
*/
|
|
58
117
|
event: Json;
|
|
59
118
|
};
|
|
60
119
|
declare type SerializedCrdtWithId = [id: string, crdt: SerializedCrdt];
|
|
120
|
+
/**
|
|
121
|
+
* Sent by the WebSocket server to a single client in response to the client
|
|
122
|
+
* joining the Room, to provide the initial Storage state of the Room. The
|
|
123
|
+
* payload includes the entire Storage document.
|
|
124
|
+
*/
|
|
61
125
|
declare type InitialDocumentStateMessage = {
|
|
62
126
|
type: ServerMessageType.InitialStorageState;
|
|
63
127
|
items: SerializedCrdtWithId[];
|
|
64
128
|
};
|
|
129
|
+
/**
|
|
130
|
+
* Sent by the WebSocket server and broadcasted to all clients to announce that
|
|
131
|
+
* a change occurred in the Storage document.
|
|
132
|
+
*
|
|
133
|
+
* The payload of this message contains a list of Ops (aka incremental
|
|
134
|
+
* mutations to make to the initially loaded document).
|
|
135
|
+
*/
|
|
65
136
|
declare type UpdateStorageMessage = {
|
|
66
137
|
type: ServerMessageType.UpdateStorage;
|
|
67
138
|
ops: Op[];
|
|
68
139
|
};
|
|
140
|
+
/**
|
|
141
|
+
* Messages that can be sent from the client to the server.
|
|
142
|
+
*/
|
|
69
143
|
declare type ClientMessage = ClientEventMessage | UpdatePresenceClientMessage | UpdateStorageClientMessage | FetchStorageClientMessage;
|
|
70
144
|
declare enum ClientMessageType {
|
|
71
145
|
UpdatePresence = 100,
|
|
@@ -129,6 +203,10 @@ declare enum OpType {
|
|
|
129
203
|
CreateMap = 7,
|
|
130
204
|
CreateRegister = 8
|
|
131
205
|
}
|
|
206
|
+
/**
|
|
207
|
+
* These operations are the payload for {@link UpdateStorageMessage} messages
|
|
208
|
+
* only.
|
|
209
|
+
*/
|
|
132
210
|
declare type Op = CreateObjectOp | UpdateObjectOp | DeleteCrdtOp | CreateListOp | SetParentKeyOp | DeleteObjectKeyOp | CreateMapOp | CreateRegisterOp;
|
|
133
211
|
declare type CreateOp = CreateObjectOp | CreateRegisterOp | CreateMapOp | CreateListOp;
|
|
134
212
|
declare type UpdateObjectOp = {
|
|
@@ -169,7 +247,7 @@ declare type CreateRegisterOp = {
|
|
|
169
247
|
type: OpType.CreateRegister;
|
|
170
248
|
parentId: string;
|
|
171
249
|
parentKey: string;
|
|
172
|
-
data:
|
|
250
|
+
data: Json;
|
|
173
251
|
};
|
|
174
252
|
declare type DeleteCrdtOp = {
|
|
175
253
|
opId?: string;
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liveblocks/client",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.3",
|
|
4
4
|
"description": "A client that lets you interact with Liveblocks servers.",
|
|
5
|
-
"main": "./
|
|
6
|
-
"types": "./
|
|
5
|
+
"main": "./index.js",
|
|
6
|
+
"types": "./index.d.ts",
|
|
7
7
|
"files": [
|
|
8
|
-
"
|
|
8
|
+
"**"
|
|
9
9
|
],
|
|
10
10
|
"exports": {
|
|
11
11
|
"./package.json": "./package.json",
|
|
12
12
|
".": {
|
|
13
|
-
"types": "./
|
|
14
|
-
"module": "./
|
|
15
|
-
"import": "./
|
|
16
|
-
"default": "./
|
|
13
|
+
"types": "./index.d.ts",
|
|
14
|
+
"module": "./esm/index.js",
|
|
15
|
+
"import": "./esm/index.mjs",
|
|
16
|
+
"default": "./index.js"
|
|
17
17
|
},
|
|
18
18
|
"./internal": {
|
|
19
|
-
"types": "./
|
|
20
|
-
"module": "./
|
|
21
|
-
"import": "./
|
|
22
|
-
"default": "./
|
|
19
|
+
"types": "./internal.d.ts",
|
|
20
|
+
"module": "./esm/internal.js",
|
|
21
|
+
"import": "./esm/internal.mjs",
|
|
22
|
+
"default": "./internal.js"
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
25
|
"keywords": [
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"url": "https://github.com/liveblocks/liveblocks/issues"
|
|
33
33
|
},
|
|
34
34
|
"scripts": {
|
|
35
|
-
"build": "rollup -c",
|
|
35
|
+
"build": "rollup -c && cp ./package.json ./README.md ./lib",
|
|
36
36
|
"test": "jest --watch",
|
|
37
37
|
"test-ci": "jest"
|
|
38
38
|
},
|