@liveblocks/client 0.16.15 → 0.17.0-beta1
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/index.d.ts +28 -8
- package/index.js +1290 -830
- package/index.mjs +1091 -782
- package/internal.d.ts +418 -248
- package/internal.js +313 -168
- package/internal.mjs +264 -130
- package/package.json +15 -10
- package/shared.d.ts +719 -650
- package/shared.js +2571 -1331
- package/shared.mjs +1992 -1209
package/index.js
CHANGED
|
@@ -1,857 +1,1317 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
var LiveObject = require("./shared.js"), _excluded = [ "_hasReceivedInitialPresence" ], BACKOFF_RETRY_DELAYS = [ 250, 500, 1e3, 2e3, 4e3, 8e3, 1e4 ], BACKOFF_RETRY_DELAYS_SLOW = [ 2e3, 3e4, 6e4, 3e5 ];
|
|
8
|
-
|
|
9
|
-
function isValidRoomEventType(value) {
|
|
10
|
-
return "my-presence" === value || "others" === value || "event" === value || "error" === value || "connection" === value;
|
|
11
|
-
}
|
|
12
|
-
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: !0 });
|
|
3
|
+
var Json = require("./shared.js"),
|
|
4
|
+
_excluded = ["_hasReceivedInitialPresence"],
|
|
5
|
+
BACKOFF_RETRY_DELAYS = [250, 500, 1e3, 2e3, 4e3, 8e3, 1e4],
|
|
6
|
+
BACKOFF_RETRY_DELAYS_SLOW = [2e3, 3e4, 6e4, 3e5];
|
|
13
7
|
function makeOthers(userMap) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
8
|
+
var _ref,
|
|
9
|
+
users = Object.values(userMap).map(function (user) {
|
|
10
|
+
return (
|
|
11
|
+
user._hasReceivedInitialPresence,
|
|
12
|
+
Json._objectWithoutPropertiesLoose(user, _excluded)
|
|
13
|
+
);
|
|
14
|
+
});
|
|
15
|
+
return (
|
|
16
|
+
((_ref = {
|
|
17
|
+
get count() {
|
|
18
|
+
return users.length;
|
|
19
|
+
},
|
|
20
|
+
})[Symbol.iterator] = function () {
|
|
21
|
+
return users[Symbol.iterator]();
|
|
22
|
+
}),
|
|
23
|
+
(_ref.map = function (callback) {
|
|
24
|
+
return users.map(callback);
|
|
25
|
+
}),
|
|
26
|
+
(_ref.toArray = function () {
|
|
27
|
+
return users;
|
|
28
|
+
}),
|
|
29
|
+
_ref
|
|
30
|
+
);
|
|
28
31
|
}
|
|
29
|
-
|
|
30
32
|
function makeStateMachine(state, context, mockedEffects) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
function
|
|
66
|
-
|
|
67
|
-
|
|
33
|
+
var effects = mockedEffects || {
|
|
34
|
+
authenticate: function (auth, createWebSocket) {
|
|
35
|
+
var rawToken = state.token,
|
|
36
|
+
parsedToken = null !== rawToken && Json.parseRoomAuthToken(rawToken);
|
|
37
|
+
if (!parsedToken || Json.isTokenExpired(parsedToken))
|
|
38
|
+
return auth(context.roomId)
|
|
39
|
+
.then(function (_ref2) {
|
|
40
|
+
var token = _ref2.token;
|
|
41
|
+
"authenticating" === state.connection.state &&
|
|
42
|
+
(authenticationSuccess(
|
|
43
|
+
Json.parseRoomAuthToken(token),
|
|
44
|
+
createWebSocket(token)
|
|
45
|
+
),
|
|
46
|
+
(state.token = token));
|
|
47
|
+
})
|
|
48
|
+
.catch(function (er) {
|
|
49
|
+
return (function (error) {
|
|
50
|
+
"production" !== process.env.NODE_ENV &&
|
|
51
|
+
console.error("Call to authentication endpoint failed", error);
|
|
52
|
+
(state.token = null),
|
|
53
|
+
updateConnection({ state: "unavailable" }),
|
|
54
|
+
state.numberOfRetry++,
|
|
55
|
+
(state.timeoutHandles.reconnect = effects.scheduleReconnect(
|
|
56
|
+
getRetryDelay()
|
|
57
|
+
));
|
|
58
|
+
})(er instanceof Error ? er : new Error(String(er)));
|
|
59
|
+
});
|
|
60
|
+
authenticationSuccess(parsedToken, createWebSocket(rawToken));
|
|
61
|
+
},
|
|
62
|
+
send: function (messageOrMessages) {
|
|
63
|
+
if (null == state.socket)
|
|
64
|
+
throw new Error("Can't send message if socket is null");
|
|
65
|
+
state.socket.send(JSON.stringify(messageOrMessages));
|
|
66
|
+
},
|
|
67
|
+
delayFlush: function (delay) {
|
|
68
|
+
return setTimeout(tryFlushing, delay);
|
|
69
|
+
},
|
|
70
|
+
startHeartbeatInterval: function () {
|
|
71
|
+
return setInterval(heartbeat, 3e4);
|
|
72
|
+
},
|
|
73
|
+
schedulePongTimeout: function () {
|
|
74
|
+
return setTimeout(pongTimeout, 2e3);
|
|
75
|
+
},
|
|
76
|
+
scheduleReconnect: function (delay) {
|
|
77
|
+
return setTimeout(connect, delay);
|
|
78
|
+
},
|
|
68
79
|
};
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
var
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
state.items.delete(id);
|
|
105
|
-
}
|
|
106
|
-
function getItem(id) {
|
|
107
|
-
return state.items.get(id);
|
|
108
|
-
}
|
|
109
|
-
function addToUndoStack(historyItem) {
|
|
110
|
-
var _state$pausedHistory;
|
|
111
|
-
(state.undoStack.length >= 50 && state.undoStack.shift(), state.isHistoryPaused) ? (_state$pausedHistory = state.pausedHistory).unshift.apply(_state$pausedHistory, historyItem) : state.undoStack.push(historyItem);
|
|
112
|
-
}
|
|
113
|
-
function storageDispatch(ops, reverse, storageUpdates) {
|
|
114
|
-
var _state$batch$ops, _state$batch$reverseO;
|
|
115
|
-
state.isBatching ? ((_state$batch$ops = state.batch.ops).push.apply(_state$batch$ops, ops),
|
|
116
|
-
storageUpdates.forEach((function(value, key) {
|
|
117
|
-
state.batch.updates.storageUpdates.set(key, LiveObject.mergeStorageUpdates(state.batch.updates.storageUpdates.get(key), value));
|
|
118
|
-
})), (_state$batch$reverseO = state.batch.reverseOps).push.apply(_state$batch$reverseO, reverse)) : (addToUndoStack(reverse),
|
|
119
|
-
state.redoStack = [], dispatch(ops), notify({
|
|
120
|
-
storageUpdates: storageUpdates
|
|
121
|
-
}));
|
|
122
|
-
}
|
|
123
|
-
function notify(_ref3) {
|
|
124
|
-
var _ref3$storageUpdates = _ref3.storageUpdates, storageUpdates = void 0 === _ref3$storageUpdates ? new Map : _ref3$storageUpdates, _ref3$presence = _ref3.presence, presence = void 0 !== _ref3$presence && _ref3$presence, _ref3$others = _ref3.others, otherEvents = void 0 === _ref3$others ? [] : _ref3$others;
|
|
125
|
-
if (otherEvents.length > 0) {
|
|
126
|
-
state.others = makeOthers(state.users);
|
|
127
|
-
for (var _step3, _iterator3 = LiveObject._createForOfIteratorHelperLoose(otherEvents); !(_step3 = _iterator3()).done; ) for (var _step4, _event = _step3.value, _iterator4 = LiveObject._createForOfIteratorHelperLoose(state.listeners.others); !(_step4 = _iterator4()).done; ) {
|
|
128
|
-
(0, _step4.value)(state.others, _event);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
if (presence) for (var _step5, _iterator5 = LiveObject._createForOfIteratorHelperLoose(state.listeners["my-presence"]); !(_step5 = _iterator5()).done; ) {
|
|
132
|
-
(0, _step5.value)(state.me);
|
|
133
|
-
}
|
|
134
|
-
if (storageUpdates.size > 0) for (var _step6, _iterator6 = LiveObject._createForOfIteratorHelperLoose(state.listeners.storage); !(_step6 = _iterator6()).done; ) {
|
|
135
|
-
(0, _step6.value)(Array.from(storageUpdates.values()));
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
function getConnectionId() {
|
|
139
|
-
if ("open" === state.connection.state || "connecting" === state.connection.state) return state.connection.id;
|
|
140
|
-
if (null !== state.lastConnectionId) return state.lastConnectionId;
|
|
141
|
-
throw new Error("Internal. Tried to get connection id but connection was never open");
|
|
142
|
-
}
|
|
143
|
-
function generateId() {
|
|
144
|
-
return getConnectionId() + ":" + state.clock++;
|
|
145
|
-
}
|
|
146
|
-
function generateOpId() {
|
|
147
|
-
return getConnectionId() + ":" + state.opClock++;
|
|
148
|
-
}
|
|
149
|
-
function apply(item, isLocal) {
|
|
150
|
-
for (var _step7, result = {
|
|
151
|
-
reverse: [],
|
|
152
|
-
updates: {
|
|
153
|
-
storageUpdates: new Map,
|
|
154
|
-
presence: !1
|
|
155
|
-
}
|
|
156
|
-
}, createdNodeIds = new Set, _iterator7 = LiveObject._createForOfIteratorHelperLoose(item); !(_step7 = _iterator7()).done; ) {
|
|
157
|
-
var op = _step7.value;
|
|
158
|
-
if ("presence" === op.type) {
|
|
159
|
-
var reverse = {
|
|
160
|
-
type: "presence",
|
|
161
|
-
data: {}
|
|
162
|
-
};
|
|
163
|
-
for (var _key2 in op.data) reverse.data[_key2] = state.me[_key2];
|
|
164
|
-
if (state.me = LiveObject._extends({}, state.me, op.data), null == state.buffer.presence) state.buffer.presence = op.data; else for (var _key3 in op.data) state.buffer.presence[_key3] = op.data[_key3];
|
|
165
|
-
result.reverse.unshift(reverse), result.updates.presence = !0;
|
|
166
|
-
} else {
|
|
167
|
-
isLocal && !op.opId && (op.opId = generateOpId());
|
|
168
|
-
var applyOpResult = applyOp(op, isLocal);
|
|
169
|
-
if (applyOpResult.modified) {
|
|
170
|
-
var _applyOpResult$modifi, _result$reverse, parentId = null == (_applyOpResult$modifi = applyOpResult.modified.node._parent) ? void 0 : _applyOpResult$modifi._id;
|
|
171
|
-
if (!createdNodeIds.has(parentId)) result.updates.storageUpdates.set(applyOpResult.modified.node._id, LiveObject.mergeStorageUpdates(result.updates.storageUpdates.get(applyOpResult.modified.node._id), applyOpResult.modified)),
|
|
172
|
-
(_result$reverse = result.reverse).unshift.apply(_result$reverse, applyOpResult.reverse);
|
|
173
|
-
op.type !== LiveObject.OpCode.CREATE_LIST && op.type !== LiveObject.OpCode.CREATE_MAP && op.type !== LiveObject.OpCode.CREATE_OBJECT || createdNodeIds.add(applyOpResult.modified.node._id);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
return result;
|
|
178
|
-
}
|
|
179
|
-
function applyOp(op, isLocal) {
|
|
180
|
-
switch (op.opId && state.offlineOperations.delete(op.opId), op.type) {
|
|
181
|
-
case LiveObject.OpCode.DELETE_OBJECT_KEY:
|
|
182
|
-
case LiveObject.OpCode.UPDATE_OBJECT:
|
|
183
|
-
case LiveObject.OpCode.DELETE_CRDT:
|
|
184
|
-
var item = state.items.get(op.id);
|
|
185
|
-
return null == item ? {
|
|
186
|
-
modified: !1
|
|
187
|
-
} : item._apply(op, isLocal);
|
|
80
|
+
function genericSubscribe(callback) {
|
|
81
|
+
return (
|
|
82
|
+
state.listeners.storage.push(callback),
|
|
83
|
+
function () {
|
|
84
|
+
return Json.remove(state.listeners.storage, callback);
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
function createOrUpdateRootFromMessage(message) {
|
|
89
|
+
if (0 === message.items.length)
|
|
90
|
+
throw new Error("Internal error: cannot load storage without items");
|
|
91
|
+
var items, _buildRootAndParentTo, root, parentToChildren;
|
|
92
|
+
for (var _key in (state.root
|
|
93
|
+
? (function (items) {
|
|
94
|
+
if (!state.root) return;
|
|
95
|
+
var currentItems = new Map();
|
|
96
|
+
state.items.forEach(function (liveCrdt, id) {
|
|
97
|
+
currentItems.set(id, liveCrdt._toSerializedCrdt());
|
|
98
|
+
}),
|
|
99
|
+
notify(
|
|
100
|
+
apply(
|
|
101
|
+
Json.getTreesDiffOperations(currentItems, new Map(items)),
|
|
102
|
+
!1
|
|
103
|
+
).updates
|
|
104
|
+
);
|
|
105
|
+
})(message.items)
|
|
106
|
+
: (state.root =
|
|
107
|
+
((items = message.items),
|
|
108
|
+
(_buildRootAndParentTo = (function (items) {
|
|
109
|
+
for (
|
|
110
|
+
var _step2,
|
|
111
|
+
parentToChildren = new Map(),
|
|
112
|
+
root = null,
|
|
113
|
+
_iterator2 = Json._createForOfIteratorHelperLoose(items);
|
|
114
|
+
!(_step2 = _iterator2()).done;
|
|
188
115
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
116
|
+
) {
|
|
117
|
+
var _step2$value = _step2.value,
|
|
118
|
+
id = _step2$value[0],
|
|
119
|
+
crdt = _step2$value[1];
|
|
120
|
+
if (Json.isRootCrdt(crdt)) root = [id, crdt];
|
|
121
|
+
else {
|
|
122
|
+
var tuple = [id, crdt],
|
|
123
|
+
children = parentToChildren.get(crdt.parentId);
|
|
124
|
+
null != children
|
|
125
|
+
? children.push(tuple)
|
|
126
|
+
: parentToChildren.set(crdt.parentId, [tuple]);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (null == root) throw new Error("Root can't be null");
|
|
130
|
+
return [root, parentToChildren];
|
|
131
|
+
})(items)),
|
|
132
|
+
(root = _buildRootAndParentTo[0]),
|
|
133
|
+
(parentToChildren = _buildRootAndParentTo[1]),
|
|
134
|
+
Json.LiveObject._deserialize(root, parentToChildren, {
|
|
135
|
+
getItem: getItem,
|
|
136
|
+
addItem: addItem,
|
|
137
|
+
deleteItem: deleteItem,
|
|
138
|
+
generateId: generateId,
|
|
139
|
+
generateOpId: generateOpId,
|
|
140
|
+
dispatch: storageDispatch,
|
|
141
|
+
roomId: context.roomId,
|
|
142
|
+
}))),
|
|
143
|
+
state.defaultStorageRoot))
|
|
144
|
+
null == state.root.get(_key) &&
|
|
145
|
+
state.root.set(_key, state.defaultStorageRoot[_key]);
|
|
146
|
+
}
|
|
147
|
+
function addItem(id, liveItem) {
|
|
148
|
+
state.items.set(id, liveItem);
|
|
149
|
+
}
|
|
150
|
+
function deleteItem(id) {
|
|
151
|
+
state.items.delete(id);
|
|
152
|
+
}
|
|
153
|
+
function getItem(id) {
|
|
154
|
+
return state.items.get(id);
|
|
155
|
+
}
|
|
156
|
+
function addToUndoStack(historyItem) {
|
|
157
|
+
var _state$pausedHistory;
|
|
158
|
+
(state.undoStack.length >= 50 && state.undoStack.shift(),
|
|
159
|
+
state.isHistoryPaused)
|
|
160
|
+
? (_state$pausedHistory = state.pausedHistory).unshift.apply(
|
|
161
|
+
_state$pausedHistory,
|
|
162
|
+
historyItem
|
|
163
|
+
)
|
|
164
|
+
: state.undoStack.push(historyItem);
|
|
165
|
+
}
|
|
166
|
+
function storageDispatch(ops, reverse, storageUpdates) {
|
|
167
|
+
var _state$batch$ops, _state$batch$reverseO;
|
|
168
|
+
state.isBatching
|
|
169
|
+
? ((_state$batch$ops = state.batch.ops).push.apply(_state$batch$ops, ops),
|
|
170
|
+
storageUpdates.forEach(function (value, key) {
|
|
171
|
+
state.batch.updates.storageUpdates.set(
|
|
172
|
+
key,
|
|
173
|
+
Json.mergeStorageUpdates(
|
|
174
|
+
state.batch.updates.storageUpdates.get(key),
|
|
175
|
+
value
|
|
176
|
+
)
|
|
177
|
+
);
|
|
178
|
+
}),
|
|
179
|
+
(_state$batch$reverseO = state.batch.reverseOps).push.apply(
|
|
180
|
+
_state$batch$reverseO,
|
|
181
|
+
reverse
|
|
182
|
+
))
|
|
183
|
+
: (addToUndoStack(reverse),
|
|
184
|
+
(state.redoStack = []),
|
|
185
|
+
dispatch(ops),
|
|
186
|
+
notify({ storageUpdates: storageUpdates }));
|
|
187
|
+
}
|
|
188
|
+
function notify(_ref3) {
|
|
189
|
+
var _ref3$storageUpdates = _ref3.storageUpdates,
|
|
190
|
+
storageUpdates =
|
|
191
|
+
void 0 === _ref3$storageUpdates ? new Map() : _ref3$storageUpdates,
|
|
192
|
+
_ref3$presence = _ref3.presence,
|
|
193
|
+
presence = void 0 !== _ref3$presence && _ref3$presence,
|
|
194
|
+
_ref3$others = _ref3.others,
|
|
195
|
+
otherEvents = void 0 === _ref3$others ? [] : _ref3$others;
|
|
196
|
+
if (otherEvents.length > 0) {
|
|
197
|
+
state.others = makeOthers(state.users);
|
|
198
|
+
for (
|
|
199
|
+
var _step3,
|
|
200
|
+
_iterator3 = Json._createForOfIteratorHelperLoose(otherEvents);
|
|
201
|
+
!(_step3 = _iterator3()).done;
|
|
203
202
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
function connect() {
|
|
215
|
-
if ("closed" !== state.connection.state && "unavailable" !== state.connection.state) return null;
|
|
216
|
-
var auth = function(authentication, fetchPolyfill) {
|
|
217
|
-
if ("public" === authentication.type) {
|
|
218
|
-
if ("undefined" == typeof window && null == fetchPolyfill) throw new Error("To use Liveblocks client in a non-dom environment with a publicApiKey, you need to provide a fetch polyfill.");
|
|
219
|
-
return function(room) {
|
|
220
|
-
return fetchAuthEndpoint(fetchPolyfill || fetch, authentication.url, {
|
|
221
|
-
room: room,
|
|
222
|
-
publicApiKey: authentication.publicApiKey
|
|
223
|
-
});
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
if ("private" === authentication.type) {
|
|
227
|
-
if ("undefined" == typeof window && null == fetchPolyfill) throw new Error("To use Liveblocks client in a non-dom environment with a url as auth endpoint, you need to provide a fetch polyfill.");
|
|
228
|
-
return function(room) {
|
|
229
|
-
return fetchAuthEndpoint(fetchPolyfill || fetch, authentication.url, {
|
|
230
|
-
room: room
|
|
231
|
-
});
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
if ("custom" === authentication.type) return authentication.callback;
|
|
235
|
-
throw new Error("Internal error. Unexpected authentication type");
|
|
236
|
-
}(context.authentication, context.fetchPolyfill), createWebSocket = function(liveblocksServer, WebSocketPolyfill) {
|
|
237
|
-
if ("undefined" == typeof window && null == WebSocketPolyfill) throw new Error("To use Liveblocks client in a non-dom environment, you need to provide a WebSocket polyfill.");
|
|
238
|
-
var ws = WebSocketPolyfill || WebSocket;
|
|
239
|
-
return function(token) {
|
|
240
|
-
return new ws(liveblocksServer + "/?token=" + token);
|
|
241
|
-
};
|
|
242
|
-
}(context.liveblocksServer, context.WebSocketPolyfill);
|
|
243
|
-
updateConnection({
|
|
244
|
-
state: "authenticating"
|
|
245
|
-
}), effects.authenticate(auth, createWebSocket);
|
|
246
|
-
}
|
|
247
|
-
function authenticationSuccess(token, socket) {
|
|
248
|
-
var connectionId, count;
|
|
249
|
-
socket.addEventListener("message", onMessage), socket.addEventListener("open", onOpen),
|
|
250
|
-
socket.addEventListener("close", onClose), socket.addEventListener("error", onError),
|
|
251
|
-
updateConnection({
|
|
252
|
-
state: "connecting",
|
|
253
|
-
id: token.actor,
|
|
254
|
-
userInfo: token.info,
|
|
255
|
-
userId: token.id
|
|
256
|
-
}), state.idFactory = (connectionId = token.actor, count = 0, function() {
|
|
257
|
-
return connectionId + ":" + count++;
|
|
258
|
-
}), state.socket = socket;
|
|
259
|
-
}
|
|
260
|
-
function onUpdatePresenceMessage(message) {
|
|
261
|
-
var user = state.users[message.actor];
|
|
262
|
-
if (void 0 !== message.targetActor || null == user || user._hasReceivedInitialPresence) return state.users[message.actor] = null == user ? {
|
|
263
|
-
connectionId: message.actor,
|
|
264
|
-
presence: message.data,
|
|
265
|
-
_hasReceivedInitialPresence: !0
|
|
266
|
-
} : {
|
|
267
|
-
id: user.id,
|
|
268
|
-
info: user.info,
|
|
269
|
-
connectionId: message.actor,
|
|
270
|
-
presence: LiveObject._extends({}, user.presence, message.data),
|
|
271
|
-
_hasReceivedInitialPresence: !0
|
|
272
|
-
}, {
|
|
273
|
-
type: "update",
|
|
274
|
-
updates: message.data,
|
|
275
|
-
user: state.users[message.actor]
|
|
276
|
-
};
|
|
277
|
-
}
|
|
278
|
-
function onUserLeftMessage(message) {
|
|
279
|
-
var userLeftMessage = message, user = state.users[userLeftMessage.actor];
|
|
280
|
-
return user ? (delete state.users[userLeftMessage.actor], {
|
|
281
|
-
type: "leave",
|
|
282
|
-
user: user
|
|
283
|
-
}) : null;
|
|
284
|
-
}
|
|
285
|
-
function onRoomStateMessage(message) {
|
|
286
|
-
var newUsers = {};
|
|
287
|
-
for (var _key5 in message.users) {
|
|
288
|
-
var _connectionId = Number.parseInt(_key5), user = message.users[_key5];
|
|
289
|
-
newUsers[_connectionId] = {
|
|
290
|
-
connectionId: _connectionId,
|
|
291
|
-
info: user.info,
|
|
292
|
-
id: user.id
|
|
293
|
-
};
|
|
294
|
-
}
|
|
295
|
-
return state.users = newUsers, {
|
|
296
|
-
type: "reset"
|
|
297
|
-
};
|
|
298
|
-
}
|
|
299
|
-
function onEvent(message) {
|
|
300
|
-
for (var _step8, _iterator8 = LiveObject._createForOfIteratorHelperLoose(state.listeners.event); !(_step8 = _iterator8()).done; ) {
|
|
301
|
-
(0, _step8.value)({
|
|
302
|
-
connectionId: message.actor,
|
|
303
|
-
event: message.event
|
|
304
|
-
});
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
function onUserJoinedMessage(message) {
|
|
308
|
-
return state.users[message.actor] = {
|
|
309
|
-
connectionId: message.actor,
|
|
310
|
-
info: message.info,
|
|
311
|
-
id: message.id,
|
|
312
|
-
_hasReceivedInitialPresence: !0
|
|
313
|
-
}, state.me && (state.buffer.messages.push({
|
|
314
|
-
type: LiveObject.ClientMsgCode.UPDATE_PRESENCE,
|
|
315
|
-
data: state.me,
|
|
316
|
-
targetActor: message.actor
|
|
317
|
-
}), tryFlushing()), {
|
|
318
|
-
type: "enter",
|
|
319
|
-
user: state.users[message.actor]
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
|
-
function parseServerMessage(data) {
|
|
323
|
-
return LiveObject.isJsonObject(data) ? data : null;
|
|
324
|
-
}
|
|
325
|
-
function onMessage(event) {
|
|
326
|
-
if ("pong" !== event.data) {
|
|
327
|
-
var text, data, messages = (text = event.data, void 0 === (data = LiveObject.tryParseJson(text)) ? null : LiveObject.isJsonArray(data) ? LiveObject.compact(data.map((function(item) {
|
|
328
|
-
return parseServerMessage(item);
|
|
329
|
-
}))) : LiveObject.compact([ parseServerMessage(data) ]));
|
|
330
|
-
if (null !== messages && 0 !== messages.length) {
|
|
331
|
-
for (var _step9, updates = {
|
|
332
|
-
storageUpdates: new Map,
|
|
333
|
-
others: []
|
|
334
|
-
}, _iterator9 = LiveObject._createForOfIteratorHelperLoose(messages); !(_step9 = _iterator9()).done; ) {
|
|
335
|
-
var message = _step9.value;
|
|
336
|
-
switch (message.type) {
|
|
337
|
-
case LiveObject.ServerMsgCode.USER_JOINED:
|
|
338
|
-
updates.others.push(onUserJoinedMessage(message));
|
|
339
|
-
break;
|
|
203
|
+
)
|
|
204
|
+
for (
|
|
205
|
+
var _step4,
|
|
206
|
+
_event = _step3.value,
|
|
207
|
+
_iterator4 = Json._createForOfIteratorHelperLoose(
|
|
208
|
+
state.listeners.others
|
|
209
|
+
);
|
|
210
|
+
!(_step4 = _iterator4()).done;
|
|
340
211
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
212
|
+
) {
|
|
213
|
+
(0, _step4.value)(state.others, _event);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (presence)
|
|
217
|
+
for (
|
|
218
|
+
var _step5,
|
|
219
|
+
_iterator5 = Json._createForOfIteratorHelperLoose(
|
|
220
|
+
state.listeners["my-presence"]
|
|
221
|
+
);
|
|
222
|
+
!(_step5 = _iterator5()).done;
|
|
345
223
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
224
|
+
) {
|
|
225
|
+
(0, _step5.value)(state.me);
|
|
226
|
+
}
|
|
227
|
+
if (storageUpdates.size > 0)
|
|
228
|
+
for (
|
|
229
|
+
var _step6,
|
|
230
|
+
_iterator6 = Json._createForOfIteratorHelperLoose(
|
|
231
|
+
state.listeners.storage
|
|
232
|
+
);
|
|
233
|
+
!(_step6 = _iterator6()).done;
|
|
349
234
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
235
|
+
) {
|
|
236
|
+
(0, _step6.value)(Array.from(storageUpdates.values()));
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
function getConnectionId() {
|
|
240
|
+
if (
|
|
241
|
+
"open" === state.connection.state ||
|
|
242
|
+
"connecting" === state.connection.state
|
|
243
|
+
)
|
|
244
|
+
return state.connection.id;
|
|
245
|
+
if (null !== state.lastConnectionId) return state.lastConnectionId;
|
|
246
|
+
throw new Error(
|
|
247
|
+
"Internal. Tried to get connection id but connection was never open"
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
function generateId() {
|
|
251
|
+
return getConnectionId() + ":" + state.clock++;
|
|
252
|
+
}
|
|
253
|
+
function generateOpId() {
|
|
254
|
+
return getConnectionId() + ":" + state.opClock++;
|
|
255
|
+
}
|
|
256
|
+
function apply(item, isLocal) {
|
|
257
|
+
for (
|
|
258
|
+
var _step7,
|
|
259
|
+
result = {
|
|
260
|
+
reverse: [],
|
|
261
|
+
updates: { storageUpdates: new Map(), presence: !1 },
|
|
262
|
+
},
|
|
263
|
+
createdNodeIds = new Set(),
|
|
264
|
+
_iterator7 = Json._createForOfIteratorHelperLoose(item);
|
|
265
|
+
!(_step7 = _iterator7()).done;
|
|
354
266
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
267
|
+
) {
|
|
268
|
+
var op = _step7.value;
|
|
269
|
+
if ("presence" === op.type) {
|
|
270
|
+
var reverse = { type: "presence", data: {} };
|
|
271
|
+
for (var _key2 in op.data) reverse.data[_key2] = state.me[_key2];
|
|
272
|
+
if (
|
|
273
|
+
((state.me = Json._extends({}, state.me, op.data)),
|
|
274
|
+
null == state.buffer.presence)
|
|
275
|
+
)
|
|
276
|
+
state.buffer.presence = op.data;
|
|
277
|
+
else
|
|
278
|
+
for (var _key3 in op.data)
|
|
279
|
+
state.buffer.presence[_key3] = op.data[_key3];
|
|
280
|
+
result.reverse.unshift(reverse), (result.updates.presence = !0);
|
|
281
|
+
} else {
|
|
282
|
+
var source = void 0;
|
|
283
|
+
if ((op.opId || (op.opId = generateOpId()), isLocal))
|
|
284
|
+
source = Json.OpSource.UNDOREDO_RECONNECT;
|
|
285
|
+
else
|
|
286
|
+
source = state.offlineOperations.delete(Json.nn(op.opId))
|
|
287
|
+
? Json.OpSource.ACK
|
|
288
|
+
: Json.OpSource.REMOTE;
|
|
289
|
+
var applyOpResult = applyOp(op, source);
|
|
290
|
+
if (applyOpResult.modified) {
|
|
291
|
+
var _result$reverse,
|
|
292
|
+
parentId =
|
|
293
|
+
"HasParent" === applyOpResult.modified.node.parent.type
|
|
294
|
+
? Json.nn(
|
|
295
|
+
applyOpResult.modified.node.parent.node._id,
|
|
296
|
+
"Expected parent node to have an ID"
|
|
297
|
+
)
|
|
298
|
+
: void 0;
|
|
299
|
+
if (!parentId || !createdNodeIds.has(parentId))
|
|
300
|
+
result.updates.storageUpdates.set(
|
|
301
|
+
Json.nn(applyOpResult.modified.node._id),
|
|
302
|
+
Json.mergeStorageUpdates(
|
|
303
|
+
result.updates.storageUpdates.get(
|
|
304
|
+
Json.nn(applyOpResult.modified.node._id)
|
|
305
|
+
),
|
|
306
|
+
applyOpResult.modified
|
|
307
|
+
)
|
|
308
|
+
),
|
|
309
|
+
(_result$reverse = result.reverse).unshift.apply(
|
|
310
|
+
_result$reverse,
|
|
311
|
+
applyOpResult.reverse
|
|
312
|
+
);
|
|
313
|
+
(op.type !== Json.OpCode.CREATE_LIST &&
|
|
314
|
+
op.type !== Json.OpCode.CREATE_MAP &&
|
|
315
|
+
op.type !== Json.OpCode.CREATE_OBJECT) ||
|
|
316
|
+
createdNodeIds.add(Json.nn(applyOpResult.modified.node._id));
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return result;
|
|
321
|
+
}
|
|
322
|
+
function applyOp(op, source) {
|
|
323
|
+
switch (op.type) {
|
|
324
|
+
case Json.OpCode.DELETE_OBJECT_KEY:
|
|
325
|
+
case Json.OpCode.UPDATE_OBJECT:
|
|
326
|
+
case Json.OpCode.DELETE_CRDT:
|
|
327
|
+
var item = state.items.get(op.id);
|
|
328
|
+
return null == item
|
|
329
|
+
? { modified: !1 }
|
|
330
|
+
: item._apply(op, source === Json.OpSource.UNDOREDO_RECONNECT);
|
|
331
|
+
case Json.OpCode.SET_PARENT_KEY:
|
|
332
|
+
var _item = state.items.get(op.id);
|
|
333
|
+
return null == _item
|
|
334
|
+
? { modified: !1 }
|
|
335
|
+
: "HasParent" === _item.parent.type &&
|
|
336
|
+
Json.isLiveList(_item.parent.node)
|
|
337
|
+
? _item.parent.node._setChildKey(op.parentKey, _item, source)
|
|
338
|
+
: { modified: !1 };
|
|
339
|
+
case Json.OpCode.CREATE_OBJECT:
|
|
340
|
+
case Json.OpCode.CREATE_LIST:
|
|
341
|
+
case Json.OpCode.CREATE_MAP:
|
|
342
|
+
case Json.OpCode.CREATE_REGISTER:
|
|
343
|
+
if (void 0 === op.parentId) return { modified: !1 };
|
|
344
|
+
var parent = state.items.get(op.parentId);
|
|
345
|
+
return null == parent
|
|
346
|
+
? { modified: !1 }
|
|
347
|
+
: parent._attachChild(op, source);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
function connect() {
|
|
351
|
+
var _context$polyfills$fe,
|
|
352
|
+
_context$polyfills,
|
|
353
|
+
_context$polyfills$We,
|
|
354
|
+
_context$polyfills2;
|
|
355
|
+
if (
|
|
356
|
+
"closed" !== state.connection.state &&
|
|
357
|
+
"unavailable" !== state.connection.state
|
|
358
|
+
)
|
|
359
|
+
return null;
|
|
360
|
+
var auth = (function (authentication, fetchPolyfill) {
|
|
361
|
+
if ("public" === authentication.type) {
|
|
362
|
+
if ("undefined" == typeof window && null == fetchPolyfill)
|
|
363
|
+
throw new Error(
|
|
364
|
+
"To use Liveblocks client in a non-dom environment with a publicApiKey, you need to provide a fetch polyfill."
|
|
365
|
+
);
|
|
366
|
+
return function (room) {
|
|
367
|
+
return fetchAuthEndpoint(
|
|
368
|
+
fetchPolyfill || fetch,
|
|
369
|
+
authentication.url,
|
|
370
|
+
{ room: room, publicApiKey: authentication.publicApiKey }
|
|
371
|
+
);
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
if ("private" === authentication.type) {
|
|
375
|
+
if ("undefined" == typeof window && null == fetchPolyfill)
|
|
376
|
+
throw new Error(
|
|
377
|
+
"To use Liveblocks client in a non-dom environment with a url as auth endpoint, you need to provide a fetch polyfill."
|
|
378
|
+
);
|
|
379
|
+
return function (room) {
|
|
380
|
+
return fetchAuthEndpoint(
|
|
381
|
+
fetchPolyfill || fetch,
|
|
382
|
+
authentication.url,
|
|
383
|
+
{ room: room }
|
|
384
|
+
);
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
if ("custom" === authentication.type) {
|
|
388
|
+
return function (room) {
|
|
389
|
+
return authentication.callback(room).then(function (response) {
|
|
390
|
+
if (!response || !response.token)
|
|
391
|
+
throw new Error(
|
|
392
|
+
'Authentication error. We expect the authentication callback to return a token, but it does not. Hint: the return value should look like: { token: "..." }'
|
|
393
|
+
);
|
|
394
|
+
return response;
|
|
395
|
+
});
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
throw new Error("Internal error. Unexpected authentication type");
|
|
399
|
+
})(
|
|
400
|
+
context.authentication,
|
|
401
|
+
null !=
|
|
402
|
+
(_context$polyfills$fe =
|
|
403
|
+
null == (_context$polyfills = context.polyfills)
|
|
404
|
+
? void 0
|
|
405
|
+
: _context$polyfills.fetch)
|
|
406
|
+
? _context$polyfills$fe
|
|
407
|
+
: context.fetchPolyfill
|
|
408
|
+
),
|
|
409
|
+
createWebSocket = (function (liveblocksServer, WebSocketPolyfill) {
|
|
410
|
+
if ("undefined" == typeof window && null == WebSocketPolyfill)
|
|
411
|
+
throw new Error(
|
|
412
|
+
"To use Liveblocks client in a non-dom environment, you need to provide a WebSocket polyfill."
|
|
413
|
+
);
|
|
414
|
+
var ws = WebSocketPolyfill || WebSocket;
|
|
415
|
+
return function (token) {
|
|
416
|
+
return new ws(liveblocksServer + "/?token=" + token);
|
|
417
|
+
};
|
|
418
|
+
})(
|
|
419
|
+
context.liveblocksServer,
|
|
420
|
+
null !=
|
|
421
|
+
(_context$polyfills$We =
|
|
422
|
+
null == (_context$polyfills2 = context.polyfills)
|
|
423
|
+
? void 0
|
|
424
|
+
: _context$polyfills2.WebSocket)
|
|
425
|
+
? _context$polyfills$We
|
|
426
|
+
: context.WebSocketPolyfill
|
|
427
|
+
);
|
|
428
|
+
updateConnection({ state: "authenticating" }),
|
|
429
|
+
effects.authenticate(auth, createWebSocket);
|
|
430
|
+
}
|
|
431
|
+
function authenticationSuccess(token, socket) {
|
|
432
|
+
var connectionId, count;
|
|
433
|
+
socket.addEventListener("message", onMessage),
|
|
434
|
+
socket.addEventListener("open", onOpen),
|
|
435
|
+
socket.addEventListener("close", onClose),
|
|
436
|
+
socket.addEventListener("error", onError),
|
|
437
|
+
updateConnection({
|
|
438
|
+
state: "connecting",
|
|
439
|
+
id: token.actor,
|
|
440
|
+
userInfo: token.info,
|
|
441
|
+
userId: token.id,
|
|
442
|
+
}),
|
|
443
|
+
(state.idFactory =
|
|
444
|
+
((connectionId = token.actor),
|
|
445
|
+
(count = 0),
|
|
446
|
+
function () {
|
|
447
|
+
return connectionId + ":" + count++;
|
|
448
|
+
})),
|
|
449
|
+
(state.socket = socket);
|
|
450
|
+
}
|
|
451
|
+
function onUpdatePresenceMessage(message) {
|
|
452
|
+
var user = state.users[message.actor];
|
|
453
|
+
if (
|
|
454
|
+
void 0 !== message.targetActor ||
|
|
455
|
+
null == user ||
|
|
456
|
+
user._hasReceivedInitialPresence
|
|
457
|
+
)
|
|
458
|
+
return (
|
|
459
|
+
(state.users[message.actor] =
|
|
460
|
+
null == user
|
|
461
|
+
? {
|
|
462
|
+
connectionId: message.actor,
|
|
463
|
+
presence: message.data,
|
|
464
|
+
id: void 0,
|
|
465
|
+
info: void 0,
|
|
466
|
+
_hasReceivedInitialPresence: !0,
|
|
467
|
+
}
|
|
468
|
+
: {
|
|
469
|
+
id: user.id,
|
|
470
|
+
info: user.info,
|
|
471
|
+
connectionId: message.actor,
|
|
472
|
+
presence: Json._extends({}, user.presence, message.data),
|
|
473
|
+
_hasReceivedInitialPresence: !0,
|
|
474
|
+
}),
|
|
475
|
+
{
|
|
476
|
+
type: "update",
|
|
477
|
+
updates: message.data,
|
|
478
|
+
user: state.users[message.actor],
|
|
479
|
+
}
|
|
480
|
+
);
|
|
481
|
+
}
|
|
482
|
+
function onUserLeftMessage(message) {
|
|
483
|
+
var userLeftMessage = message,
|
|
484
|
+
user = state.users[userLeftMessage.actor];
|
|
485
|
+
return user
|
|
486
|
+
? (delete state.users[userLeftMessage.actor],
|
|
487
|
+
{ type: "leave", user: user })
|
|
488
|
+
: null;
|
|
489
|
+
}
|
|
490
|
+
function onRoomStateMessage(message) {
|
|
491
|
+
var newUsers = {};
|
|
492
|
+
for (var _key5 in message.users) {
|
|
493
|
+
var _connectionId = Number.parseInt(_key5),
|
|
494
|
+
user = message.users[_key5];
|
|
495
|
+
newUsers[_connectionId] = {
|
|
496
|
+
connectionId: _connectionId,
|
|
497
|
+
info: user.info,
|
|
498
|
+
id: user.id,
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
return (state.users = newUsers), { type: "reset" };
|
|
502
|
+
}
|
|
503
|
+
function onEvent(message) {
|
|
504
|
+
for (
|
|
505
|
+
var _step8,
|
|
506
|
+
_iterator8 = Json._createForOfIteratorHelperLoose(
|
|
507
|
+
state.listeners.event
|
|
508
|
+
);
|
|
509
|
+
!(_step8 = _iterator8()).done;
|
|
510
|
+
|
|
511
|
+
) {
|
|
512
|
+
(0, _step8.value)({ connectionId: message.actor, event: message.event });
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
function onUserJoinedMessage(message) {
|
|
516
|
+
return (
|
|
517
|
+
(state.users[message.actor] = {
|
|
518
|
+
connectionId: message.actor,
|
|
519
|
+
info: message.info,
|
|
520
|
+
id: message.id,
|
|
521
|
+
_hasReceivedInitialPresence: !0,
|
|
522
|
+
}),
|
|
523
|
+
state.me &&
|
|
524
|
+
(state.buffer.messages.push({
|
|
525
|
+
type: Json.ClientMsgCode.UPDATE_PRESENCE,
|
|
526
|
+
data: state.me,
|
|
527
|
+
targetActor: message.actor,
|
|
528
|
+
}),
|
|
529
|
+
tryFlushing()),
|
|
530
|
+
{ type: "enter", user: state.users[message.actor] }
|
|
531
|
+
);
|
|
532
|
+
}
|
|
533
|
+
function parseServerMessage(data) {
|
|
534
|
+
return Json.isJsonObject(data) ? data : null;
|
|
535
|
+
}
|
|
536
|
+
function onMessage(event) {
|
|
537
|
+
if ("pong" !== event.data) {
|
|
538
|
+
var text,
|
|
539
|
+
data,
|
|
540
|
+
messages =
|
|
541
|
+
((text = event.data),
|
|
542
|
+
void 0 === (data = Json.tryParseJson(text))
|
|
543
|
+
? null
|
|
544
|
+
: Json.isJsonArray(data)
|
|
545
|
+
? Json.compact(
|
|
546
|
+
data.map(function (item) {
|
|
547
|
+
return parseServerMessage(item);
|
|
548
|
+
})
|
|
549
|
+
)
|
|
550
|
+
: Json.compact([parseServerMessage(data)]));
|
|
551
|
+
if (null !== messages && 0 !== messages.length) {
|
|
552
|
+
for (
|
|
553
|
+
var _step9,
|
|
554
|
+
updates = { storageUpdates: new Map(), others: [] },
|
|
555
|
+
_iterator9 = Json._createForOfIteratorHelperLoose(messages);
|
|
556
|
+
!(_step9 = _iterator9()).done;
|
|
358
557
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
558
|
+
) {
|
|
559
|
+
var message = _step9.value;
|
|
560
|
+
switch (message.type) {
|
|
561
|
+
case Json.ServerMsgCode.USER_JOINED:
|
|
562
|
+
updates.others.push(onUserJoinedMessage(message));
|
|
563
|
+
break;
|
|
564
|
+
case Json.ServerMsgCode.UPDATE_PRESENCE:
|
|
565
|
+
var othersPresenceUpdate = onUpdatePresenceMessage(message);
|
|
566
|
+
othersPresenceUpdate && updates.others.push(othersPresenceUpdate);
|
|
567
|
+
break;
|
|
568
|
+
case Json.ServerMsgCode.BROADCASTED_EVENT:
|
|
569
|
+
onEvent(message);
|
|
570
|
+
break;
|
|
571
|
+
case Json.ServerMsgCode.USER_LEFT:
|
|
572
|
+
var _event2 = onUserLeftMessage(message);
|
|
573
|
+
_event2 && updates.others.push(_event2);
|
|
574
|
+
break;
|
|
575
|
+
case Json.ServerMsgCode.ROOM_STATE:
|
|
576
|
+
updates.others.push(onRoomStateMessage(message));
|
|
577
|
+
break;
|
|
578
|
+
case Json.ServerMsgCode.INITIAL_STORAGE_STATE:
|
|
579
|
+
var offlineOps = new Map(state.offlineOperations);
|
|
580
|
+
createOrUpdateRootFromMessage(message),
|
|
581
|
+
applyAndSendOfflineOps(offlineOps),
|
|
582
|
+
null == _getInitialStateResolver || _getInitialStateResolver();
|
|
583
|
+
break;
|
|
584
|
+
case Json.ServerMsgCode.UPDATE_STORAGE:
|
|
585
|
+
apply(message.ops, !1).updates.storageUpdates.forEach(function (
|
|
586
|
+
value,
|
|
587
|
+
key
|
|
588
|
+
) {
|
|
589
|
+
updates.storageUpdates.set(
|
|
590
|
+
key,
|
|
591
|
+
Json.mergeStorageUpdates(
|
|
592
|
+
updates.storageUpdates.get(key),
|
|
593
|
+
value
|
|
594
|
+
)
|
|
595
|
+
);
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
notify(updates);
|
|
600
|
+
}
|
|
601
|
+
} else clearTimeout(state.timeoutHandles.pongTimeout);
|
|
602
|
+
}
|
|
603
|
+
function onClose(event) {
|
|
604
|
+
if (
|
|
605
|
+
((state.socket = null),
|
|
606
|
+
clearTimeout(state.timeoutHandles.pongTimeout),
|
|
607
|
+
clearInterval(state.intervalHandles.heartbeat),
|
|
608
|
+
state.timeoutHandles.flush && clearTimeout(state.timeoutHandles.flush),
|
|
609
|
+
clearTimeout(state.timeoutHandles.reconnect),
|
|
610
|
+
(state.users = {}),
|
|
611
|
+
notify({ others: [{ type: "reset" }] }),
|
|
612
|
+
event.code >= 4e3 && event.code <= 4100)
|
|
613
|
+
) {
|
|
614
|
+
updateConnection({ state: "failed" });
|
|
615
|
+
for (
|
|
616
|
+
var _step10,
|
|
617
|
+
error = new LiveblocksError(event.reason, event.code),
|
|
618
|
+
_iterator10 = Json._createForOfIteratorHelperLoose(
|
|
619
|
+
state.listeners.error
|
|
620
|
+
);
|
|
621
|
+
!(_step10 = _iterator10()).done;
|
|
363
622
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
623
|
+
) {
|
|
624
|
+
(0, _step10.value)(error);
|
|
625
|
+
}
|
|
626
|
+
var _delay = getRetryDelay(!0);
|
|
627
|
+
state.numberOfRetry++,
|
|
628
|
+
"production" !== process.env.NODE_ENV &&
|
|
629
|
+
console.error(
|
|
630
|
+
"Connection to Liveblocks websocket server closed. Reason: " +
|
|
631
|
+
error.message +
|
|
632
|
+
" (code: " +
|
|
633
|
+
error.code +
|
|
634
|
+
"). Retrying in " +
|
|
635
|
+
_delay +
|
|
636
|
+
"ms."
|
|
637
|
+
),
|
|
638
|
+
updateConnection({ state: "unavailable" }),
|
|
639
|
+
(state.timeoutHandles.reconnect = effects.scheduleReconnect(_delay));
|
|
640
|
+
} else if (event.code === Json.WebsocketCloseCodes.CLOSE_WITHOUT_RETRY)
|
|
641
|
+
updateConnection({ state: "closed" });
|
|
642
|
+
else {
|
|
643
|
+
var _delay2 = getRetryDelay();
|
|
644
|
+
state.numberOfRetry++,
|
|
645
|
+
"production" !== process.env.NODE_ENV &&
|
|
646
|
+
console.warn(
|
|
647
|
+
"Connection to Liveblocks websocket server closed (code: " +
|
|
648
|
+
event.code +
|
|
649
|
+
"). Retrying in " +
|
|
650
|
+
_delay2 +
|
|
651
|
+
"ms."
|
|
652
|
+
),
|
|
653
|
+
updateConnection({ state: "unavailable" }),
|
|
654
|
+
(state.timeoutHandles.reconnect = effects.scheduleReconnect(_delay2));
|
|
369
655
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
updateConnection({
|
|
383
|
-
state: "failed"
|
|
384
|
-
});
|
|
385
|
-
for (var _step10, error = new LiveblocksError(event.reason, event.code), _iterator10 = LiveObject._createForOfIteratorHelperLoose(state.listeners.error); !(_step10 = _iterator10()).done; ) {
|
|
386
|
-
(0, _step10.value)(error);
|
|
387
|
-
}
|
|
388
|
-
var _delay = getRetryDelay(!0);
|
|
389
|
-
state.numberOfRetry++, "production" !== process.env.NODE_ENV && console.error("Connection to Liveblocks websocket server closed. Reason: " + error.message + " (code: " + error.code + "). Retrying in " + _delay + "ms."),
|
|
390
|
-
updateConnection({
|
|
391
|
-
state: "unavailable"
|
|
392
|
-
}), state.timeoutHandles.reconnect = effects.scheduleReconnect(_delay);
|
|
393
|
-
} else if (event.code === LiveObject.WebsocketCloseCodes.CLOSE_WITHOUT_RETRY) updateConnection({
|
|
394
|
-
state: "closed"
|
|
395
|
-
}); else {
|
|
396
|
-
var _delay2 = getRetryDelay();
|
|
397
|
-
state.numberOfRetry++, "production" !== process.env.NODE_ENV && console.warn("Connection to Liveblocks websocket server closed (code: " + event.code + "). Retrying in " + _delay2 + "ms."),
|
|
398
|
-
updateConnection({
|
|
399
|
-
state: "unavailable"
|
|
400
|
-
}), state.timeoutHandles.reconnect = effects.scheduleReconnect(_delay2);
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
function updateConnection(connection) {
|
|
404
|
-
state.connection = connection;
|
|
405
|
-
for (var _step11, _iterator11 = LiveObject._createForOfIteratorHelperLoose(state.listeners.connection); !(_step11 = _iterator11()).done; ) {
|
|
406
|
-
(0, _step11.value)(connection.state);
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
function getRetryDelay(slow) {
|
|
410
|
-
return void 0 === slow && (slow = !1), slow ? BACKOFF_RETRY_DELAYS_SLOW[state.numberOfRetry < BACKOFF_RETRY_DELAYS_SLOW.length ? state.numberOfRetry : BACKOFF_RETRY_DELAYS_SLOW.length - 1] : BACKOFF_RETRY_DELAYS[state.numberOfRetry < BACKOFF_RETRY_DELAYS.length ? state.numberOfRetry : BACKOFF_RETRY_DELAYS.length - 1];
|
|
411
|
-
}
|
|
412
|
-
function onError() {}
|
|
413
|
-
function onOpen() {
|
|
414
|
-
clearInterval(state.intervalHandles.heartbeat), state.intervalHandles.heartbeat = effects.startHeartbeatInterval(),
|
|
415
|
-
"connecting" === state.connection.state && (updateConnection(LiveObject._extends({}, state.connection, {
|
|
416
|
-
state: "open"
|
|
417
|
-
})), state.numberOfRetry = 0, void 0 !== state.lastConnectionId && (state.buffer.presence = state.me,
|
|
418
|
-
tryFlushing()), state.lastConnectionId = state.connection.id, state.root && state.buffer.messages.push({
|
|
419
|
-
type: LiveObject.ClientMsgCode.FETCH_STORAGE
|
|
420
|
-
}), tryFlushing());
|
|
421
|
-
}
|
|
422
|
-
function heartbeat() {
|
|
423
|
-
null != state.socket && (clearTimeout(state.timeoutHandles.pongTimeout), state.timeoutHandles.pongTimeout = effects.schedulePongTimeout(),
|
|
424
|
-
state.socket.readyState === state.socket.OPEN && state.socket.send("ping"));
|
|
425
|
-
}
|
|
426
|
-
function pongTimeout() {
|
|
427
|
-
reconnect();
|
|
428
|
-
}
|
|
429
|
-
function reconnect() {
|
|
430
|
-
state.socket && (state.socket.removeEventListener("open", onOpen), state.socket.removeEventListener("message", onMessage),
|
|
431
|
-
state.socket.removeEventListener("close", onClose), state.socket.removeEventListener("error", onError),
|
|
432
|
-
state.socket.close(), state.socket = null), updateConnection({
|
|
433
|
-
state: "unavailable"
|
|
434
|
-
}), clearTimeout(state.timeoutHandles.pongTimeout), state.timeoutHandles.flush && clearTimeout(state.timeoutHandles.flush),
|
|
435
|
-
clearTimeout(state.timeoutHandles.reconnect), clearInterval(state.intervalHandles.heartbeat),
|
|
436
|
-
connect();
|
|
437
|
-
}
|
|
438
|
-
function applyAndSendOfflineOps(offlineOps) {
|
|
439
|
-
if (0 !== offlineOps.size) {
|
|
440
|
-
var messages = [], ops = Array.from(offlineOps.values()), result = apply(ops, !0);
|
|
441
|
-
messages.push({
|
|
442
|
-
type: LiveObject.ClientMsgCode.UPDATE_STORAGE,
|
|
443
|
-
ops: ops
|
|
444
|
-
}), notify(result.updates), effects.send(messages);
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
function tryFlushing() {
|
|
448
|
-
var storageOps = state.buffer.storageOperations;
|
|
449
|
-
if (storageOps.length > 0 && storageOps.forEach((function(op) {
|
|
450
|
-
state.offlineOperations.set(op.opId, op);
|
|
451
|
-
})), null != state.socket && state.socket.readyState === state.socket.OPEN) {
|
|
452
|
-
var now = Date.now();
|
|
453
|
-
if (now - state.lastFlushTime > context.throttleDelay) {
|
|
454
|
-
var _messages = function(state) {
|
|
455
|
-
var messages = [];
|
|
456
|
-
state.buffer.presence && messages.push({
|
|
457
|
-
type: LiveObject.ClientMsgCode.UPDATE_PRESENCE,
|
|
458
|
-
data: state.buffer.presence
|
|
459
|
-
});
|
|
460
|
-
for (var _step12, _iterator12 = LiveObject._createForOfIteratorHelperLoose(state.buffer.messages); !(_step12 = _iterator12()).done; ) {
|
|
461
|
-
var _event3 = _step12.value;
|
|
462
|
-
messages.push(_event3);
|
|
463
|
-
}
|
|
464
|
-
state.buffer.storageOperations.length > 0 && messages.push({
|
|
465
|
-
type: LiveObject.ClientMsgCode.UPDATE_STORAGE,
|
|
466
|
-
ops: state.buffer.storageOperations
|
|
467
|
-
});
|
|
468
|
-
return messages;
|
|
469
|
-
}(state);
|
|
470
|
-
if (0 === _messages.length) return;
|
|
471
|
-
effects.send(_messages), state.buffer = {
|
|
472
|
-
messages: [],
|
|
473
|
-
storageOperations: [],
|
|
474
|
-
presence: null
|
|
475
|
-
}, state.lastFlushTime = now;
|
|
476
|
-
} else null != state.timeoutHandles.flush && clearTimeout(state.timeoutHandles.flush),
|
|
477
|
-
state.timeoutHandles.flush = effects.delayFlush(context.throttleDelay - (now - state.lastFlushTime));
|
|
478
|
-
} else state.buffer.storageOperations = [];
|
|
479
|
-
}
|
|
480
|
-
function getPresence() {
|
|
481
|
-
return state.me;
|
|
482
|
-
}
|
|
483
|
-
function dispatch(ops) {
|
|
484
|
-
var _state$buffer$storage;
|
|
485
|
-
(_state$buffer$storage = state.buffer.storageOperations).push.apply(_state$buffer$storage, ops),
|
|
486
|
-
tryFlushing();
|
|
487
|
-
}
|
|
488
|
-
var _getInitialStatePromise = null, _getInitialStateResolver = null;
|
|
489
|
-
return {
|
|
490
|
-
onClose: onClose,
|
|
491
|
-
onMessage: onMessage,
|
|
492
|
-
authenticationSuccess: authenticationSuccess,
|
|
493
|
-
heartbeat: heartbeat,
|
|
494
|
-
onNavigatorOnline: function() {
|
|
495
|
-
"unavailable" === state.connection.state && reconnect();
|
|
496
|
-
},
|
|
497
|
-
simulateSocketClose: function() {
|
|
498
|
-
state.socket && state.socket.close();
|
|
499
|
-
},
|
|
500
|
-
simulateSendCloseEvent: function(event) {
|
|
501
|
-
state.socket && onClose(event);
|
|
502
|
-
},
|
|
503
|
-
onVisibilityChange: function(visibilityState) {
|
|
504
|
-
"visible" === visibilityState && "open" === state.connection.state && heartbeat();
|
|
505
|
-
},
|
|
506
|
-
getUndoStack: function() {
|
|
507
|
-
return state.undoStack;
|
|
508
|
-
},
|
|
509
|
-
getItemsCount: function() {
|
|
510
|
-
return state.items.size;
|
|
511
|
-
},
|
|
512
|
-
connect: connect,
|
|
513
|
-
disconnect: function() {
|
|
514
|
-
state.socket && (state.socket.removeEventListener("open", onOpen), state.socket.removeEventListener("message", onMessage),
|
|
515
|
-
state.socket.removeEventListener("close", onClose), state.socket.removeEventListener("error", onError),
|
|
516
|
-
state.socket.close(), state.socket = null), updateConnection({
|
|
517
|
-
state: "closed"
|
|
518
|
-
}), state.timeoutHandles.flush && clearTimeout(state.timeoutHandles.flush), clearTimeout(state.timeoutHandles.reconnect),
|
|
519
|
-
clearTimeout(state.timeoutHandles.pongTimeout), clearInterval(state.intervalHandles.heartbeat),
|
|
520
|
-
state.users = {}, notify({
|
|
521
|
-
others: [ {
|
|
522
|
-
type: "reset"
|
|
523
|
-
} ]
|
|
524
|
-
}), function() {
|
|
525
|
-
for (var _key6 in state.listeners) state.listeners[_key6] = [];
|
|
526
|
-
}();
|
|
527
|
-
},
|
|
528
|
-
subscribe: function(firstParam, listener, options) {
|
|
529
|
-
if (firstParam instanceof LiveObject.AbstractCrdt) return function(crdt, innerCallback, options) {
|
|
530
|
-
return genericSubscribe((function(updates) {
|
|
531
|
-
for (var _step, relatedUpdates = [], _iterator = LiveObject._createForOfIteratorHelperLoose(updates); !(_step = _iterator()).done; ) {
|
|
532
|
-
var update = _step.value;
|
|
533
|
-
null != options && options.isDeep && LiveObject.isSameNodeOrChildOf(update.node, crdt) ? relatedUpdates.push(update) : update.node._id === crdt._id && innerCallback(update.node);
|
|
534
|
-
}
|
|
535
|
-
null != options && options.isDeep && relatedUpdates.length > 0 && innerCallback(relatedUpdates);
|
|
536
|
-
}));
|
|
537
|
-
}(firstParam, listener, options);
|
|
538
|
-
if ("function" == typeof firstParam) return genericSubscribe(firstParam);
|
|
539
|
-
if (!isValidRoomEventType(firstParam)) throw new Error('"' + firstParam + '" is not a valid event name');
|
|
540
|
-
return state.listeners[firstParam].push(listener), function() {
|
|
541
|
-
var callbacks = state.listeners[firstParam];
|
|
542
|
-
LiveObject.remove(callbacks, listener);
|
|
543
|
-
};
|
|
544
|
-
},
|
|
545
|
-
unsubscribe: function(event, callback) {
|
|
546
|
-
if (console.warn("unsubscribe is depreacted and will be removed in a future version.\nuse the callback returned by subscribe instead.\nSee v0.13 release notes for more information.\n"),
|
|
547
|
-
!isValidRoomEventType(event)) throw new Error('"' + event + '" is not a valid event name');
|
|
548
|
-
var callbacks = state.listeners[event];
|
|
549
|
-
LiveObject.remove(callbacks, callback);
|
|
550
|
-
},
|
|
551
|
-
updatePresence: function(overrides, options) {
|
|
552
|
-
var oldValues = {};
|
|
553
|
-
for (var _key4 in null == state.buffer.presence && (state.buffer.presence = {}),
|
|
554
|
-
overrides) state.buffer.presence[_key4] = overrides[_key4], oldValues[_key4] = state.me[_key4];
|
|
555
|
-
state.me = LiveObject._extends({}, state.me, overrides), state.isBatching ? (null != options && options.addToHistory && state.batch.reverseOps.push({
|
|
556
|
-
type: "presence",
|
|
557
|
-
data: oldValues
|
|
558
|
-
}), state.batch.updates.presence = !0) : (tryFlushing(), null != options && options.addToHistory && addToUndoStack([ {
|
|
559
|
-
type: "presence",
|
|
560
|
-
data: oldValues
|
|
561
|
-
} ]), notify({
|
|
562
|
-
presence: !0
|
|
563
|
-
}));
|
|
564
|
-
},
|
|
565
|
-
broadcastEvent: function(event, options) {
|
|
566
|
-
void 0 === options && (options = {
|
|
567
|
-
shouldQueueEventIfNotReady: !1
|
|
568
|
-
}), null == state.socket && 0 == options.shouldQueueEventIfNotReady || (state.buffer.messages.push({
|
|
569
|
-
type: LiveObject.ClientMsgCode.BROADCAST_EVENT,
|
|
570
|
-
event: event
|
|
571
|
-
}), tryFlushing());
|
|
572
|
-
},
|
|
573
|
-
batch: function(callback) {
|
|
574
|
-
if (state.isBatching) throw new Error("batch should not be called during a batch");
|
|
575
|
-
state.isBatching = !0;
|
|
576
|
-
try {
|
|
577
|
-
callback();
|
|
578
|
-
} finally {
|
|
579
|
-
state.isBatching = !1, state.batch.reverseOps.length > 0 && addToUndoStack(state.batch.reverseOps),
|
|
580
|
-
state.batch.ops.length > 0 && (state.redoStack = []), state.batch.ops.length > 0 && dispatch(state.batch.ops),
|
|
581
|
-
notify(state.batch.updates), state.batch = {
|
|
582
|
-
ops: [],
|
|
583
|
-
reverseOps: [],
|
|
584
|
-
updates: {
|
|
585
|
-
others: [],
|
|
586
|
-
storageUpdates: new Map,
|
|
587
|
-
presence: !1
|
|
588
|
-
}
|
|
589
|
-
}, tryFlushing();
|
|
590
|
-
}
|
|
591
|
-
},
|
|
592
|
-
undo: function() {
|
|
593
|
-
if (state.isBatching) throw new Error("undo is not allowed during a batch");
|
|
594
|
-
var historyItem = state.undoStack.pop();
|
|
595
|
-
if (null != historyItem) {
|
|
596
|
-
state.isHistoryPaused = !1;
|
|
597
|
-
var result = apply(historyItem, !0);
|
|
598
|
-
notify(result.updates), state.redoStack.push(result.reverse);
|
|
599
|
-
for (var _step13, _iterator13 = LiveObject._createForOfIteratorHelperLoose(historyItem); !(_step13 = _iterator13()).done; ) {
|
|
600
|
-
var op = _step13.value;
|
|
601
|
-
"presence" !== op.type && state.buffer.storageOperations.push(op);
|
|
656
|
+
}
|
|
657
|
+
function updateConnection(connection) {
|
|
658
|
+
state.connection = connection;
|
|
659
|
+
for (
|
|
660
|
+
var _step11,
|
|
661
|
+
_iterator11 = Json._createForOfIteratorHelperLoose(
|
|
662
|
+
state.listeners.connection
|
|
663
|
+
);
|
|
664
|
+
!(_step11 = _iterator11()).done;
|
|
665
|
+
|
|
666
|
+
) {
|
|
667
|
+
(0, _step11.value)(connection.state);
|
|
602
668
|
}
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
669
|
+
}
|
|
670
|
+
function getRetryDelay(slow) {
|
|
671
|
+
return (
|
|
672
|
+
void 0 === slow && (slow = !1),
|
|
673
|
+
slow
|
|
674
|
+
? BACKOFF_RETRY_DELAYS_SLOW[
|
|
675
|
+
state.numberOfRetry < BACKOFF_RETRY_DELAYS_SLOW.length
|
|
676
|
+
? state.numberOfRetry
|
|
677
|
+
: BACKOFF_RETRY_DELAYS_SLOW.length - 1
|
|
678
|
+
]
|
|
679
|
+
: BACKOFF_RETRY_DELAYS[
|
|
680
|
+
state.numberOfRetry < BACKOFF_RETRY_DELAYS.length
|
|
681
|
+
? state.numberOfRetry
|
|
682
|
+
: BACKOFF_RETRY_DELAYS.length - 1
|
|
683
|
+
]
|
|
684
|
+
);
|
|
685
|
+
}
|
|
686
|
+
function onError() {}
|
|
687
|
+
function onOpen() {
|
|
688
|
+
clearInterval(state.intervalHandles.heartbeat),
|
|
689
|
+
(state.intervalHandles.heartbeat = effects.startHeartbeatInterval()),
|
|
690
|
+
"connecting" === state.connection.state &&
|
|
691
|
+
(updateConnection(
|
|
692
|
+
Json._extends({}, state.connection, { state: "open" })
|
|
693
|
+
),
|
|
694
|
+
(state.numberOfRetry = 0),
|
|
695
|
+
void 0 !== state.lastConnectionId &&
|
|
696
|
+
((state.buffer.presence = state.me), tryFlushing()),
|
|
697
|
+
(state.lastConnectionId = state.connection.id),
|
|
698
|
+
state.root &&
|
|
699
|
+
state.buffer.messages.push({
|
|
700
|
+
type: Json.ClientMsgCode.FETCH_STORAGE,
|
|
701
|
+
}),
|
|
702
|
+
tryFlushing());
|
|
703
|
+
}
|
|
704
|
+
function heartbeat() {
|
|
705
|
+
null != state.socket &&
|
|
706
|
+
(clearTimeout(state.timeoutHandles.pongTimeout),
|
|
707
|
+
(state.timeoutHandles.pongTimeout = effects.schedulePongTimeout()),
|
|
708
|
+
state.socket.readyState === state.socket.OPEN &&
|
|
709
|
+
state.socket.send("ping"));
|
|
710
|
+
}
|
|
711
|
+
function pongTimeout() {
|
|
712
|
+
reconnect();
|
|
713
|
+
}
|
|
714
|
+
function reconnect() {
|
|
715
|
+
state.socket &&
|
|
716
|
+
(state.socket.removeEventListener("open", onOpen),
|
|
717
|
+
state.socket.removeEventListener("message", onMessage),
|
|
718
|
+
state.socket.removeEventListener("close", onClose),
|
|
719
|
+
state.socket.removeEventListener("error", onError),
|
|
720
|
+
state.socket.close(),
|
|
721
|
+
(state.socket = null)),
|
|
722
|
+
updateConnection({ state: "unavailable" }),
|
|
723
|
+
clearTimeout(state.timeoutHandles.pongTimeout),
|
|
724
|
+
state.timeoutHandles.flush && clearTimeout(state.timeoutHandles.flush),
|
|
725
|
+
clearTimeout(state.timeoutHandles.reconnect),
|
|
726
|
+
clearInterval(state.intervalHandles.heartbeat),
|
|
727
|
+
connect();
|
|
728
|
+
}
|
|
729
|
+
function applyAndSendOfflineOps(offlineOps) {
|
|
730
|
+
if (0 !== offlineOps.size) {
|
|
731
|
+
var messages = [],
|
|
732
|
+
ops = Array.from(offlineOps.values()),
|
|
733
|
+
result = apply(ops, !0);
|
|
734
|
+
messages.push({ type: Json.ClientMsgCode.UPDATE_STORAGE, ops: ops }),
|
|
735
|
+
notify(result.updates),
|
|
736
|
+
effects.send(messages);
|
|
616
737
|
}
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
selectors: {
|
|
643
|
-
getConnectionState: function() {
|
|
644
|
-
return state.connection.state;
|
|
645
|
-
},
|
|
646
|
-
getSelf: function() {
|
|
647
|
-
return "open" === state.connection.state || "connecting" === state.connection.state ? {
|
|
648
|
-
connectionId: state.connection.id,
|
|
649
|
-
id: state.connection.userId,
|
|
650
|
-
info: state.connection.userInfo,
|
|
651
|
-
presence: getPresence()
|
|
652
|
-
} : null;
|
|
653
|
-
},
|
|
654
|
-
getPresence: getPresence,
|
|
655
|
-
getOthers: function() {
|
|
656
|
-
return state.others;
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
};
|
|
660
|
-
}
|
|
738
|
+
}
|
|
739
|
+
function tryFlushing() {
|
|
740
|
+
var storageOps = state.buffer.storageOperations;
|
|
741
|
+
if (
|
|
742
|
+
(storageOps.length > 0 &&
|
|
743
|
+
storageOps.forEach(function (op) {
|
|
744
|
+
state.offlineOperations.set(Json.nn(op.opId), op);
|
|
745
|
+
}),
|
|
746
|
+
null != state.socket && state.socket.readyState === state.socket.OPEN)
|
|
747
|
+
) {
|
|
748
|
+
var now = Date.now();
|
|
749
|
+
if (now - state.lastFlushTime > context.throttleDelay) {
|
|
750
|
+
var _messages = (function (state) {
|
|
751
|
+
var messages = [];
|
|
752
|
+
state.buffer.presence &&
|
|
753
|
+
messages.push({
|
|
754
|
+
type: Json.ClientMsgCode.UPDATE_PRESENCE,
|
|
755
|
+
data: state.buffer.presence,
|
|
756
|
+
});
|
|
757
|
+
for (
|
|
758
|
+
var _step12,
|
|
759
|
+
_iterator12 = Json._createForOfIteratorHelperLoose(
|
|
760
|
+
state.buffer.messages
|
|
761
|
+
);
|
|
762
|
+
!(_step12 = _iterator12()).done;
|
|
661
763
|
|
|
662
|
-
|
|
663
|
-
|
|
764
|
+
) {
|
|
765
|
+
var _event3 = _step12.value;
|
|
766
|
+
messages.push(_event3);
|
|
767
|
+
}
|
|
768
|
+
state.buffer.storageOperations.length > 0 &&
|
|
769
|
+
messages.push({
|
|
770
|
+
type: Json.ClientMsgCode.UPDATE_STORAGE,
|
|
771
|
+
ops: state.buffer.storageOperations,
|
|
772
|
+
});
|
|
773
|
+
return messages;
|
|
774
|
+
})(state);
|
|
775
|
+
if (0 === _messages.length) return;
|
|
776
|
+
effects.send(_messages),
|
|
777
|
+
(state.buffer = {
|
|
778
|
+
messages: [],
|
|
779
|
+
storageOperations: [],
|
|
780
|
+
presence: null,
|
|
781
|
+
}),
|
|
782
|
+
(state.lastFlushTime = now);
|
|
783
|
+
} else
|
|
784
|
+
null != state.timeoutHandles.flush &&
|
|
785
|
+
clearTimeout(state.timeoutHandles.flush),
|
|
786
|
+
(state.timeoutHandles.flush = effects.delayFlush(
|
|
787
|
+
context.throttleDelay - (now - state.lastFlushTime)
|
|
788
|
+
));
|
|
789
|
+
} else state.buffer.storageOperations = [];
|
|
790
|
+
}
|
|
791
|
+
function getPresence() {
|
|
792
|
+
return state.me;
|
|
793
|
+
}
|
|
794
|
+
function dispatch(ops) {
|
|
795
|
+
var _state$buffer$storage;
|
|
796
|
+
(_state$buffer$storage = state.buffer.storageOperations).push.apply(
|
|
797
|
+
_state$buffer$storage,
|
|
798
|
+
ops
|
|
799
|
+
),
|
|
800
|
+
tryFlushing();
|
|
801
|
+
}
|
|
802
|
+
var _getInitialStatePromise = null,
|
|
803
|
+
_getInitialStateResolver = null;
|
|
664
804
|
return {
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
listeners: {
|
|
672
|
-
event: [],
|
|
673
|
-
others: [],
|
|
674
|
-
"my-presence": [],
|
|
675
|
-
error: [],
|
|
676
|
-
connection: [],
|
|
677
|
-
storage: []
|
|
678
|
-
},
|
|
679
|
-
numberOfRetry: 0,
|
|
680
|
-
lastFlushTime: 0,
|
|
681
|
-
timeoutHandles: {
|
|
682
|
-
flush: null,
|
|
683
|
-
reconnect: 0,
|
|
684
|
-
pongTimeout: 0
|
|
685
|
-
},
|
|
686
|
-
buffer: {
|
|
687
|
-
presence: null == initialPresence ? {} : initialPresence,
|
|
688
|
-
messages: [],
|
|
689
|
-
storageOperations: []
|
|
690
|
-
},
|
|
691
|
-
intervalHandles: {
|
|
692
|
-
heartbeat: 0
|
|
693
|
-
},
|
|
694
|
-
me: null == initialPresence ? {} : initialPresence,
|
|
695
|
-
users: {},
|
|
696
|
-
others: makeOthers({}),
|
|
697
|
-
defaultStorageRoot: initialStorage,
|
|
698
|
-
idFactory: null,
|
|
699
|
-
clock: 0,
|
|
700
|
-
opClock: 0,
|
|
701
|
-
items: new Map,
|
|
702
|
-
root: void 0,
|
|
703
|
-
undoStack: [],
|
|
704
|
-
redoStack: [],
|
|
705
|
-
isHistoryPaused: !1,
|
|
706
|
-
pausedHistory: [],
|
|
707
|
-
isBatching: !1,
|
|
708
|
-
batch: {
|
|
709
|
-
ops: [],
|
|
710
|
-
updates: {
|
|
711
|
-
storageUpdates: new Map,
|
|
712
|
-
presence: !1,
|
|
713
|
-
others: []
|
|
805
|
+
onClose: onClose,
|
|
806
|
+
onMessage: onMessage,
|
|
807
|
+
authenticationSuccess: authenticationSuccess,
|
|
808
|
+
heartbeat: heartbeat,
|
|
809
|
+
onNavigatorOnline: function () {
|
|
810
|
+
"unavailable" === state.connection.state && reconnect();
|
|
714
811
|
},
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
812
|
+
simulateSocketClose: function () {
|
|
813
|
+
state.socket && (state.socket = null);
|
|
814
|
+
},
|
|
815
|
+
simulateSendCloseEvent: function (event) {
|
|
816
|
+
onClose(event);
|
|
817
|
+
},
|
|
818
|
+
onVisibilityChange: function (visibilityState) {
|
|
819
|
+
"visible" === visibilityState &&
|
|
820
|
+
"open" === state.connection.state &&
|
|
821
|
+
heartbeat();
|
|
822
|
+
},
|
|
823
|
+
getUndoStack: function () {
|
|
824
|
+
return state.undoStack;
|
|
825
|
+
},
|
|
826
|
+
getItemsCount: function () {
|
|
827
|
+
return state.items.size;
|
|
828
|
+
},
|
|
829
|
+
connect: connect,
|
|
830
|
+
disconnect: function () {
|
|
831
|
+
state.socket &&
|
|
832
|
+
(state.socket.removeEventListener("open", onOpen),
|
|
833
|
+
state.socket.removeEventListener("message", onMessage),
|
|
834
|
+
state.socket.removeEventListener("close", onClose),
|
|
835
|
+
state.socket.removeEventListener("error", onError),
|
|
836
|
+
state.socket.close(),
|
|
837
|
+
(state.socket = null)),
|
|
838
|
+
updateConnection({ state: "closed" }),
|
|
839
|
+
state.timeoutHandles.flush && clearTimeout(state.timeoutHandles.flush),
|
|
840
|
+
clearTimeout(state.timeoutHandles.reconnect),
|
|
841
|
+
clearTimeout(state.timeoutHandles.pongTimeout),
|
|
842
|
+
clearInterval(state.intervalHandles.heartbeat),
|
|
843
|
+
(state.users = {}),
|
|
844
|
+
notify({ others: [{ type: "reset" }] }),
|
|
845
|
+
(function () {
|
|
846
|
+
for (var _key6 in state.listeners) state.listeners[_key6] = [];
|
|
847
|
+
})();
|
|
848
|
+
},
|
|
849
|
+
subscribe: function (first, second, options) {
|
|
850
|
+
if (void 0 === second || "function" == typeof first) {
|
|
851
|
+
if ("function" == typeof first) return genericSubscribe(first);
|
|
852
|
+
throw new Error("Please specify a listener callback");
|
|
853
|
+
}
|
|
854
|
+
if (Json.isLiveNode(first)) {
|
|
855
|
+
var _node = first;
|
|
856
|
+
return null != options && options.isDeep
|
|
857
|
+
? ((node = _node),
|
|
858
|
+
(callback = second),
|
|
859
|
+
genericSubscribe(function (updates) {
|
|
860
|
+
var relatedUpdates = updates.filter(function (update) {
|
|
861
|
+
return Json.isSameNodeOrChildOf(update.node, node);
|
|
862
|
+
});
|
|
863
|
+
relatedUpdates.length > 0 && callback(relatedUpdates);
|
|
864
|
+
}))
|
|
865
|
+
: (function (node, callback) {
|
|
866
|
+
return genericSubscribe(function (updates) {
|
|
867
|
+
for (
|
|
868
|
+
var _step,
|
|
869
|
+
_iterator = Json._createForOfIteratorHelperLoose(updates);
|
|
870
|
+
!(_step = _iterator()).done;
|
|
871
|
+
|
|
872
|
+
) {
|
|
873
|
+
var update = _step.value;
|
|
874
|
+
update.node._id === node._id && callback(update.node);
|
|
875
|
+
}
|
|
876
|
+
});
|
|
877
|
+
})(_node, second);
|
|
878
|
+
}
|
|
879
|
+
var node, callback;
|
|
880
|
+
if (!Json.isRoomEventName(first))
|
|
881
|
+
throw new Error('"' + first + '" is not a valid event name');
|
|
882
|
+
var eventName = first,
|
|
883
|
+
eventListener = second;
|
|
884
|
+
return (
|
|
885
|
+
state.listeners[eventName].push(eventListener),
|
|
886
|
+
function () {
|
|
887
|
+
var callbacks = state.listeners[eventName];
|
|
888
|
+
Json.remove(callbacks, eventListener);
|
|
889
|
+
}
|
|
890
|
+
);
|
|
891
|
+
},
|
|
892
|
+
updatePresence: function (overrides, options) {
|
|
893
|
+
var oldValues = {};
|
|
894
|
+
for (var _key4 in (null == state.buffer.presence &&
|
|
895
|
+
(state.buffer.presence = {}),
|
|
896
|
+
overrides)) {
|
|
897
|
+
var overrideValue = overrides[_key4];
|
|
898
|
+
void 0 !== overrideValue &&
|
|
899
|
+
((state.buffer.presence[_key4] = overrideValue),
|
|
900
|
+
(oldValues[_key4] = state.me[_key4]));
|
|
901
|
+
}
|
|
902
|
+
(state.me = Json._extends({}, state.me, overrides)),
|
|
903
|
+
state.isBatching
|
|
904
|
+
? (null != options &&
|
|
905
|
+
options.addToHistory &&
|
|
906
|
+
state.batch.reverseOps.push({
|
|
907
|
+
type: "presence",
|
|
908
|
+
data: oldValues,
|
|
909
|
+
}),
|
|
910
|
+
(state.batch.updates.presence = !0))
|
|
911
|
+
: (tryFlushing(),
|
|
912
|
+
null != options &&
|
|
913
|
+
options.addToHistory &&
|
|
914
|
+
addToUndoStack([{ type: "presence", data: oldValues }]),
|
|
915
|
+
notify({ presence: !0 }));
|
|
916
|
+
},
|
|
917
|
+
broadcastEvent: function (event, options) {
|
|
918
|
+
void 0 === options && (options = { shouldQueueEventIfNotReady: !1 }),
|
|
919
|
+
(null == state.socket && 0 == options.shouldQueueEventIfNotReady) ||
|
|
920
|
+
(state.buffer.messages.push({
|
|
921
|
+
type: Json.ClientMsgCode.BROADCAST_EVENT,
|
|
922
|
+
event: event,
|
|
923
|
+
}),
|
|
924
|
+
tryFlushing());
|
|
925
|
+
},
|
|
926
|
+
batch: function (callback) {
|
|
927
|
+
if (state.isBatching)
|
|
928
|
+
throw new Error("batch should not be called during a batch");
|
|
929
|
+
state.isBatching = !0;
|
|
930
|
+
try {
|
|
931
|
+
callback();
|
|
932
|
+
} finally {
|
|
933
|
+
(state.isBatching = !1),
|
|
934
|
+
state.batch.reverseOps.length > 0 &&
|
|
935
|
+
addToUndoStack(state.batch.reverseOps),
|
|
936
|
+
state.batch.ops.length > 0 && (state.redoStack = []),
|
|
937
|
+
state.batch.ops.length > 0 && dispatch(state.batch.ops),
|
|
938
|
+
notify(state.batch.updates),
|
|
939
|
+
(state.batch = {
|
|
940
|
+
ops: [],
|
|
941
|
+
reverseOps: [],
|
|
942
|
+
updates: { others: [], storageUpdates: new Map(), presence: !1 },
|
|
943
|
+
}),
|
|
944
|
+
tryFlushing();
|
|
945
|
+
}
|
|
946
|
+
},
|
|
947
|
+
undo: function () {
|
|
948
|
+
if (state.isBatching)
|
|
949
|
+
throw new Error("undo is not allowed during a batch");
|
|
950
|
+
var historyItem = state.undoStack.pop();
|
|
951
|
+
if (null != historyItem) {
|
|
952
|
+
state.isHistoryPaused = !1;
|
|
953
|
+
var result = apply(historyItem, !0);
|
|
954
|
+
notify(result.updates), state.redoStack.push(result.reverse);
|
|
955
|
+
for (
|
|
956
|
+
var _step13,
|
|
957
|
+
_iterator13 = Json._createForOfIteratorHelperLoose(historyItem);
|
|
958
|
+
!(_step13 = _iterator13()).done;
|
|
750
959
|
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
}
|
|
960
|
+
) {
|
|
961
|
+
var op = _step13.value;
|
|
962
|
+
"presence" !== op.type && state.buffer.storageOperations.push(op);
|
|
963
|
+
}
|
|
964
|
+
tryFlushing();
|
|
965
|
+
}
|
|
966
|
+
},
|
|
967
|
+
redo: function () {
|
|
968
|
+
if (state.isBatching)
|
|
969
|
+
throw new Error("redo is not allowed during a batch");
|
|
970
|
+
var historyItem = state.redoStack.pop();
|
|
971
|
+
if (null != historyItem) {
|
|
972
|
+
state.isHistoryPaused = !1;
|
|
973
|
+
var result = apply(historyItem, !0);
|
|
974
|
+
notify(result.updates), state.undoStack.push(result.reverse);
|
|
975
|
+
for (
|
|
976
|
+
var _step14,
|
|
977
|
+
_iterator14 = Json._createForOfIteratorHelperLoose(historyItem);
|
|
978
|
+
!(_step14 = _iterator14()).done;
|
|
757
979
|
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
980
|
+
) {
|
|
981
|
+
var op = _step14.value;
|
|
982
|
+
"presence" !== op.type && state.buffer.storageOperations.push(op);
|
|
983
|
+
}
|
|
984
|
+
tryFlushing();
|
|
985
|
+
}
|
|
986
|
+
},
|
|
987
|
+
pauseHistory: function () {
|
|
988
|
+
(state.pausedHistory = []), (state.isHistoryPaused = !0);
|
|
989
|
+
},
|
|
990
|
+
resumeHistory: function () {
|
|
991
|
+
(state.isHistoryPaused = !1),
|
|
992
|
+
state.pausedHistory.length > 0 && addToUndoStack(state.pausedHistory),
|
|
993
|
+
(state.pausedHistory = []);
|
|
994
|
+
},
|
|
995
|
+
getStorage: function () {
|
|
996
|
+
return state.root
|
|
997
|
+
? new Promise(function (resolve) {
|
|
998
|
+
return resolve({ root: state.root });
|
|
999
|
+
})
|
|
1000
|
+
: (null == _getInitialStatePromise &&
|
|
1001
|
+
(state.buffer.messages.push({
|
|
1002
|
+
type: Json.ClientMsgCode.FETCH_STORAGE,
|
|
1003
|
+
}),
|
|
1004
|
+
tryFlushing(),
|
|
1005
|
+
(_getInitialStatePromise = new Promise(function (resolve) {
|
|
1006
|
+
return (_getInitialStateResolver = resolve);
|
|
1007
|
+
}))),
|
|
1008
|
+
_getInitialStatePromise.then(function () {
|
|
1009
|
+
return { root: Json.nn(state.root) };
|
|
1010
|
+
}));
|
|
1011
|
+
},
|
|
1012
|
+
selectors: {
|
|
1013
|
+
getConnectionState: function () {
|
|
1014
|
+
return state.connection.state;
|
|
1015
|
+
},
|
|
1016
|
+
getSelf: function () {
|
|
1017
|
+
return "open" === state.connection.state ||
|
|
1018
|
+
"connecting" === state.connection.state
|
|
1019
|
+
? {
|
|
1020
|
+
connectionId: state.connection.id,
|
|
1021
|
+
id: state.connection.userId,
|
|
1022
|
+
info: state.connection.userInfo,
|
|
1023
|
+
presence: getPresence(),
|
|
1024
|
+
}
|
|
1025
|
+
: null;
|
|
1026
|
+
},
|
|
1027
|
+
getPresence: getPresence,
|
|
1028
|
+
getOthers: function () {
|
|
1029
|
+
return state.others;
|
|
1030
|
+
},
|
|
1031
|
+
},
|
|
1032
|
+
};
|
|
768
1033
|
}
|
|
769
|
-
|
|
1034
|
+
function createRoom(options, context) {
|
|
1035
|
+
var _options$initialPrese,
|
|
1036
|
+
_options$initialStora,
|
|
1037
|
+
initialPresence =
|
|
1038
|
+
null != (_options$initialPrese = options.initialPresence)
|
|
1039
|
+
? _options$initialPrese
|
|
1040
|
+
: options.defaultPresence,
|
|
1041
|
+
initialStorage =
|
|
1042
|
+
null != (_options$initialStora = options.initialStorage)
|
|
1043
|
+
? _options$initialStora
|
|
1044
|
+
: options.defaultStorageRoot,
|
|
1045
|
+
machine = makeStateMachine(
|
|
1046
|
+
(function (initialPresence, initialStorage) {
|
|
1047
|
+
return {
|
|
1048
|
+
connection: { state: "closed" },
|
|
1049
|
+
token: null,
|
|
1050
|
+
lastConnectionId: null,
|
|
1051
|
+
socket: null,
|
|
1052
|
+
listeners: {
|
|
1053
|
+
event: [],
|
|
1054
|
+
others: [],
|
|
1055
|
+
"my-presence": [],
|
|
1056
|
+
error: [],
|
|
1057
|
+
connection: [],
|
|
1058
|
+
storage: [],
|
|
1059
|
+
},
|
|
1060
|
+
numberOfRetry: 0,
|
|
1061
|
+
lastFlushTime: 0,
|
|
1062
|
+
timeoutHandles: { flush: null, reconnect: 0, pongTimeout: 0 },
|
|
1063
|
+
buffer: {
|
|
1064
|
+
presence: null == initialPresence ? {} : initialPresence,
|
|
1065
|
+
messages: [],
|
|
1066
|
+
storageOperations: [],
|
|
1067
|
+
},
|
|
1068
|
+
intervalHandles: { heartbeat: 0 },
|
|
1069
|
+
me: null == initialPresence ? {} : initialPresence,
|
|
1070
|
+
users: {},
|
|
1071
|
+
others: makeOthers({}),
|
|
1072
|
+
defaultStorageRoot: initialStorage,
|
|
1073
|
+
idFactory: null,
|
|
1074
|
+
clock: 0,
|
|
1075
|
+
opClock: 0,
|
|
1076
|
+
items: new Map(),
|
|
1077
|
+
root: void 0,
|
|
1078
|
+
undoStack: [],
|
|
1079
|
+
redoStack: [],
|
|
1080
|
+
isHistoryPaused: !1,
|
|
1081
|
+
pausedHistory: [],
|
|
1082
|
+
isBatching: !1,
|
|
1083
|
+
batch: {
|
|
1084
|
+
ops: [],
|
|
1085
|
+
updates: { storageUpdates: new Map(), presence: !1, others: [] },
|
|
1086
|
+
reverseOps: [],
|
|
1087
|
+
},
|
|
1088
|
+
offlineOperations: new Map(),
|
|
1089
|
+
};
|
|
1090
|
+
})(
|
|
1091
|
+
"function" == typeof initialPresence
|
|
1092
|
+
? initialPresence(context.roomId)
|
|
1093
|
+
: initialPresence,
|
|
1094
|
+
"function" == typeof initialStorage
|
|
1095
|
+
? initialStorage(context.roomId)
|
|
1096
|
+
: initialStorage
|
|
1097
|
+
),
|
|
1098
|
+
context
|
|
1099
|
+
),
|
|
1100
|
+
room = {
|
|
1101
|
+
id: context.roomId,
|
|
1102
|
+
getConnectionState: machine.selectors.getConnectionState,
|
|
1103
|
+
getSelf: machine.selectors.getSelf,
|
|
1104
|
+
subscribe: machine.subscribe,
|
|
1105
|
+
getPresence: machine.selectors.getPresence,
|
|
1106
|
+
updatePresence: machine.updatePresence,
|
|
1107
|
+
getOthers: machine.selectors.getOthers,
|
|
1108
|
+
broadcastEvent: machine.broadcastEvent,
|
|
1109
|
+
getStorage: machine.getStorage,
|
|
1110
|
+
batch: machine.batch,
|
|
1111
|
+
history: {
|
|
1112
|
+
undo: machine.undo,
|
|
1113
|
+
redo: machine.redo,
|
|
1114
|
+
pause: machine.pauseHistory,
|
|
1115
|
+
resume: machine.resumeHistory,
|
|
1116
|
+
},
|
|
1117
|
+
__INTERNAL_DO_NOT_USE: {
|
|
1118
|
+
simulateCloseWebsocket: machine.simulateSocketClose,
|
|
1119
|
+
simulateSendCloseEvent: machine.simulateSendCloseEvent,
|
|
1120
|
+
},
|
|
1121
|
+
};
|
|
1122
|
+
return {
|
|
1123
|
+
connect: machine.connect,
|
|
1124
|
+
disconnect: machine.disconnect,
|
|
1125
|
+
onNavigatorOnline: machine.onNavigatorOnline,
|
|
1126
|
+
onVisibilityChange: machine.onVisibilityChange,
|
|
1127
|
+
room: room,
|
|
1128
|
+
};
|
|
1129
|
+
}
|
|
1130
|
+
var LiveblocksError = (function (_Error) {
|
|
1131
|
+
function LiveblocksError(message, code) {
|
|
1132
|
+
return _Error.call(this, message) || this;
|
|
1133
|
+
}
|
|
1134
|
+
return Json._inheritsLoose(LiveblocksError, _Error), LiveblocksError;
|
|
1135
|
+
})(Json._wrapNativeSuper(Error));
|
|
770
1136
|
function fetchAuthEndpoint(fetch, endpoint, body) {
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
1137
|
+
return fetch(endpoint, {
|
|
1138
|
+
method: "POST",
|
|
1139
|
+
headers: { "Content-Type": "application/json" },
|
|
1140
|
+
body: JSON.stringify(body),
|
|
1141
|
+
})
|
|
1142
|
+
.then(function (res) {
|
|
1143
|
+
if (!res.ok)
|
|
1144
|
+
throw new AuthenticationError(
|
|
1145
|
+
"Expected a status 200 but got " +
|
|
1146
|
+
res.status +
|
|
1147
|
+
' when doing a POST request on "' +
|
|
1148
|
+
endpoint +
|
|
1149
|
+
'"'
|
|
1150
|
+
);
|
|
1151
|
+
return res.json().catch(function (er) {
|
|
1152
|
+
throw new AuthenticationError(
|
|
1153
|
+
'Expected a JSON response when doing a POST request on "' +
|
|
1154
|
+
endpoint +
|
|
1155
|
+
'". ' +
|
|
1156
|
+
er
|
|
1157
|
+
);
|
|
1158
|
+
});
|
|
1159
|
+
})
|
|
1160
|
+
.then(function (data) {
|
|
1161
|
+
if (!Json.isPlainObject(data) || "string" != typeof data.token)
|
|
1162
|
+
throw new AuthenticationError(
|
|
1163
|
+
'Expected a JSON response of the form `{ token: "..." }` when doing a POST request on "' +
|
|
1164
|
+
endpoint +
|
|
1165
|
+
'", but got ' +
|
|
1166
|
+
JSON.stringify(data)
|
|
1167
|
+
);
|
|
1168
|
+
return { token: data.token };
|
|
1169
|
+
});
|
|
786
1170
|
}
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
}(LiveObject._wrapNativeSuper(Error));
|
|
794
|
-
|
|
1171
|
+
var AuthenticationError = (function (_Error2) {
|
|
1172
|
+
function AuthenticationError(message) {
|
|
1173
|
+
return _Error2.call(this, message) || this;
|
|
1174
|
+
}
|
|
1175
|
+
return Json._inheritsLoose(AuthenticationError, _Error2), AuthenticationError;
|
|
1176
|
+
})(Json._wrapNativeSuper(Error));
|
|
795
1177
|
function prepareAuthentication(clientOptions) {
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
1178
|
+
var publicApiKey = clientOptions.publicApiKey,
|
|
1179
|
+
authEndpoint = clientOptions.authEndpoint;
|
|
1180
|
+
if (void 0 !== authEndpoint && void 0 !== publicApiKey)
|
|
1181
|
+
throw new Error(
|
|
1182
|
+
"You cannot use both publicApiKey and authEndpoint. Please use either publicApiKey or authEndpoint, but not both. For more information: https://liveblocks.io/docs/api-reference/liveblocks-client#createClient"
|
|
1183
|
+
);
|
|
1184
|
+
if ("string" == typeof publicApiKey) {
|
|
1185
|
+
if (publicApiKey.startsWith("sk_"))
|
|
1186
|
+
throw new Error(
|
|
1187
|
+
"Invalid publicApiKey. You are using the secret key which is not supported. Please use the public key instead. For more information: https://liveblocks.io/docs/api-reference/liveblocks-client#createClientPublicKey"
|
|
1188
|
+
);
|
|
1189
|
+
if (!publicApiKey.startsWith("pk_"))
|
|
1190
|
+
throw new Error(
|
|
1191
|
+
"Invalid key. Please use the public key format: pk_<public key>. For more information: https://liveblocks.io/docs/api-reference/liveblocks-client#createClientPublicKey"
|
|
1192
|
+
);
|
|
1193
|
+
return {
|
|
1194
|
+
type: "public",
|
|
1195
|
+
publicApiKey: publicApiKey,
|
|
1196
|
+
url:
|
|
1197
|
+
clientOptions.publicAuthorizeEndpoint ||
|
|
1198
|
+
"https://liveblocks.io/api/public/authorize",
|
|
1199
|
+
};
|
|
1200
|
+
}
|
|
1201
|
+
if ("string" == typeof authEndpoint)
|
|
1202
|
+
return { type: "private", url: authEndpoint };
|
|
1203
|
+
if ("function" == typeof authEndpoint)
|
|
1204
|
+
return { type: "custom", callback: authEndpoint };
|
|
1205
|
+
if (void 0 !== authEndpoint)
|
|
1206
|
+
throw new Error(
|
|
1207
|
+
"authEndpoint must be a string or a function. For more information: https://liveblocks.io/docs/api-reference/liveblocks-client#createClientAuthEndpoint"
|
|
1208
|
+
);
|
|
1209
|
+
throw new Error(
|
|
1210
|
+
"Invalid Liveblocks client options. For more information: https://liveblocks.io/docs/api-reference/liveblocks-client#createClient"
|
|
1211
|
+
);
|
|
810
1212
|
}
|
|
1213
|
+
(exports.LiveList = Json.LiveList),
|
|
1214
|
+
(exports.LiveMap = Json.LiveMap),
|
|
1215
|
+
(exports.LiveObject = Json.LiveObject),
|
|
1216
|
+
(exports.createClient = function (options) {
|
|
1217
|
+
var clientOptions = options,
|
|
1218
|
+
throttleDelay = (function (options) {
|
|
1219
|
+
if (void 0 === options.throttle) return 100;
|
|
1220
|
+
if (
|
|
1221
|
+
"number" != typeof options.throttle ||
|
|
1222
|
+
options.throttle < 80 ||
|
|
1223
|
+
options.throttle > 1e3
|
|
1224
|
+
)
|
|
1225
|
+
throw new Error("throttle should be a number between 80 and 1000.");
|
|
1226
|
+
return options.throttle;
|
|
1227
|
+
})(options),
|
|
1228
|
+
rooms = new Map();
|
|
1229
|
+
return (
|
|
1230
|
+
"undefined" != typeof window &&
|
|
1231
|
+
void 0 !== window.addEventListener &&
|
|
1232
|
+
window.addEventListener("online", function () {
|
|
1233
|
+
for (
|
|
1234
|
+
var _step, _iterator = Json._createForOfIteratorHelperLoose(rooms);
|
|
1235
|
+
!(_step = _iterator()).done;
|
|
1236
|
+
|
|
1237
|
+
) {
|
|
1238
|
+
_step.value[1].onNavigatorOnline();
|
|
1239
|
+
}
|
|
1240
|
+
}),
|
|
1241
|
+
"undefined" != typeof document &&
|
|
1242
|
+
document.addEventListener("visibilitychange", function () {
|
|
1243
|
+
for (
|
|
1244
|
+
var _step2,
|
|
1245
|
+
_iterator2 = Json._createForOfIteratorHelperLoose(rooms);
|
|
1246
|
+
!(_step2 = _iterator2()).done;
|
|
811
1247
|
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
1248
|
+
) {
|
|
1249
|
+
_step2.value[1].onVisibilityChange(document.visibilityState);
|
|
1250
|
+
}
|
|
1251
|
+
}),
|
|
1252
|
+
{
|
|
1253
|
+
getRoom: function (roomId) {
|
|
1254
|
+
var internalRoom = rooms.get(roomId);
|
|
1255
|
+
return internalRoom ? internalRoom.room : null;
|
|
1256
|
+
},
|
|
1257
|
+
enter: function (roomId, options) {
|
|
1258
|
+
void 0 === options && (options = {});
|
|
1259
|
+
var internalRoom = rooms.get(roomId);
|
|
1260
|
+
if (internalRoom) return internalRoom.room;
|
|
1261
|
+
if (
|
|
1262
|
+
(Json.errorIf(
|
|
1263
|
+
options.defaultPresence,
|
|
1264
|
+
"Argument `defaultPresence` will be removed in @liveblocks/client 0.18. Please use `initialPresence` instead. For more info, see https://bit.ly/3Niy5aP"
|
|
1265
|
+
),
|
|
1266
|
+
Json.errorIf(
|
|
1267
|
+
options.defaultStorageRoot,
|
|
1268
|
+
"Argument `defaultStorageRoot` will be removed in @liveblocks/client 0.18. Please use `initialStorage` instead. For more info, see https://bit.ly/3Niy5aP"
|
|
1269
|
+
),
|
|
1270
|
+
(internalRoom = createRoom(
|
|
1271
|
+
{
|
|
1272
|
+
initialPresence: options.initialPresence,
|
|
1273
|
+
initialStorage: options.initialStorage,
|
|
1274
|
+
defaultPresence: options.defaultPresence,
|
|
1275
|
+
defaultStorageRoot: options.defaultStorageRoot,
|
|
1276
|
+
},
|
|
1277
|
+
{
|
|
1278
|
+
roomId: roomId,
|
|
1279
|
+
throttleDelay: throttleDelay,
|
|
1280
|
+
polyfills: clientOptions.polyfills,
|
|
1281
|
+
WebSocketPolyfill: clientOptions.WebSocketPolyfill,
|
|
1282
|
+
fetchPolyfill: clientOptions.fetchPolyfill,
|
|
1283
|
+
liveblocksServer:
|
|
1284
|
+
(null == clientOptions
|
|
1285
|
+
? void 0
|
|
1286
|
+
: clientOptions.liveblocksServer) ||
|
|
1287
|
+
"wss://liveblocks.net/v6",
|
|
1288
|
+
authentication: prepareAuthentication(clientOptions),
|
|
1289
|
+
}
|
|
1290
|
+
)),
|
|
1291
|
+
rooms.set(roomId, internalRoom),
|
|
1292
|
+
!options.DO_NOT_USE_withoutConnecting)
|
|
1293
|
+
) {
|
|
1294
|
+
if ("undefined" == typeof atob) {
|
|
1295
|
+
var _clientOptions$polyfi;
|
|
1296
|
+
if (
|
|
1297
|
+
null ==
|
|
1298
|
+
(null == (_clientOptions$polyfi = clientOptions.polyfills)
|
|
1299
|
+
? void 0
|
|
1300
|
+
: _clientOptions$polyfi.atob)
|
|
1301
|
+
)
|
|
1302
|
+
throw new Error(
|
|
1303
|
+
"You need to polyfill atob to use the client in your environment. Please follow the instructions at https://liveblocks.io/docs/errors/liveblocks-client/atob-polyfill"
|
|
1304
|
+
);
|
|
1305
|
+
global.atob = clientOptions.polyfills.atob;
|
|
1306
|
+
}
|
|
1307
|
+
internalRoom.connect();
|
|
1308
|
+
}
|
|
1309
|
+
return internalRoom.room;
|
|
1310
|
+
},
|
|
1311
|
+
leave: function (roomId) {
|
|
1312
|
+
var room = rooms.get(roomId);
|
|
1313
|
+
room && (room.disconnect(), rooms.delete(roomId));
|
|
1314
|
+
},
|
|
1315
|
+
}
|
|
1316
|
+
);
|
|
1317
|
+
});
|