@liveblocks/client 0.16.4 → 0.16.7
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.js +815 -1540
- package/index.mjs +778 -1295
- package/internal.d.ts +37 -5
- package/internal.js +152 -337
- package/internal.mjs +127 -299
- package/package.json +8 -7
- package/shared.d.ts +15 -3
- package/shared.js +1276 -2380
- package/shared.mjs +1183 -1887
package/index.js
CHANGED
|
@@ -1,1582 +1,857 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
2
|
|
|
3
|
-
Object.defineProperty(exports,
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: !0
|
|
5
|
+
});
|
|
4
6
|
|
|
5
|
-
var LiveObject = require(
|
|
6
|
-
|
|
7
|
-
var BACKOFF_RETRY_DELAYS = [250, 500, 1000, 2000, 4000, 8000, 10000];
|
|
8
|
-
var BACKOFF_RETRY_DELAYS_SLOW = [2000, 30000, 60000, 300000];
|
|
9
|
-
var HEARTBEAT_INTERVAL = 30000;
|
|
10
|
-
var PONG_TIMEOUT = 2000;
|
|
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 ];
|
|
11
8
|
|
|
12
9
|
function isValidRoomEventType(value) {
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function makeIdFactory(connectionId) {
|
|
17
|
-
var count = 0;
|
|
18
|
-
return function () {
|
|
19
|
-
return connectionId + ":" + count++;
|
|
20
|
-
};
|
|
10
|
+
return "my-presence" === value || "others" === value || "event" === value || "error" === value || "connection" === value;
|
|
21
11
|
}
|
|
22
12
|
|
|
23
13
|
function makeOthers(userMap) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
return
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return users[Symbol.iterator]();
|
|
39
|
-
}, _ref.map = function map(callback) {
|
|
40
|
-
return users.map(callback);
|
|
41
|
-
}, _ref.toArray = function toArray() {
|
|
42
|
-
return users;
|
|
43
|
-
}, _ref;
|
|
14
|
+
var _ref, users = Object.values(userMap).map((function(user) {
|
|
15
|
+
return user._hasReceivedInitialPresence, LiveObject._objectWithoutPropertiesLoose(user, _excluded);
|
|
16
|
+
}));
|
|
17
|
+
return (_ref = {
|
|
18
|
+
get count() {
|
|
19
|
+
return users.length;
|
|
20
|
+
}
|
|
21
|
+
})[Symbol.iterator] = function() {
|
|
22
|
+
return users[Symbol.iterator]();
|
|
23
|
+
}, _ref.map = function(callback) {
|
|
24
|
+
return users.map(callback);
|
|
25
|
+
}, _ref.toArray = function() {
|
|
26
|
+
return users;
|
|
27
|
+
}, _ref;
|
|
44
28
|
}
|
|
45
29
|
|
|
46
30
|
function makeStateMachine(state, context, mockedEffects) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (state.connection.state !== "authenticating") {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
var parsedToken = parseToken(token);
|
|
64
|
-
var socket = createWebSocket(token);
|
|
65
|
-
authenticationSuccess(parsedToken, socket);
|
|
66
|
-
state.token = token;
|
|
67
|
-
}).catch(function (er) {
|
|
68
|
-
return authenticationFailure(er);
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
send: function send(messageOrMessages) {
|
|
73
|
-
if (state.socket == null) {
|
|
74
|
-
throw new Error("Can't send message if socket is null");
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
state.socket.send(JSON.stringify(messageOrMessages));
|
|
78
|
-
},
|
|
79
|
-
delayFlush: function delayFlush(delay) {
|
|
80
|
-
return setTimeout(tryFlushing, delay);
|
|
81
|
-
},
|
|
82
|
-
startHeartbeatInterval: function startHeartbeatInterval() {
|
|
83
|
-
return setInterval(heartbeat, HEARTBEAT_INTERVAL);
|
|
84
|
-
},
|
|
85
|
-
schedulePongTimeout: function schedulePongTimeout() {
|
|
86
|
-
return setTimeout(pongTimeout, PONG_TIMEOUT);
|
|
87
|
-
},
|
|
88
|
-
scheduleReconnect: function scheduleReconnect(delay) {
|
|
89
|
-
return setTimeout(connect, delay);
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
function genericSubscribe(callback) {
|
|
94
|
-
state.listeners.storage.push(callback);
|
|
95
|
-
return function () {
|
|
96
|
-
return LiveObject.remove(state.listeners.storage, callback);
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function crdtSubscribe(crdt, innerCallback, options) {
|
|
101
|
-
var cb = function cb(updates) {
|
|
102
|
-
var relatedUpdates = [];
|
|
103
|
-
|
|
104
|
-
for (var _iterator = LiveObject._createForOfIteratorHelperLoose(updates), _step; !(_step = _iterator()).done;) {
|
|
105
|
-
var update = _step.value;
|
|
106
|
-
|
|
107
|
-
if (options != null && options.isDeep && LiveObject.isSameNodeOrChildOf(update.node, crdt)) {
|
|
108
|
-
relatedUpdates.push(update);
|
|
109
|
-
} else if (update.node._id === crdt._id) {
|
|
110
|
-
innerCallback(update.node);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (options != null && options.isDeep && relatedUpdates.length > 0) {
|
|
115
|
-
innerCallback(relatedUpdates);
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
return genericSubscribe(cb);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function createOrUpdateRootFromMessage(message) {
|
|
123
|
-
if (message.items.length === 0) {
|
|
124
|
-
throw new Error("Internal error: cannot load storage without items");
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (state.root) {
|
|
128
|
-
updateRoot(message.items);
|
|
129
|
-
} else {
|
|
130
|
-
state.root = load(message.items);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
for (var _key in state.defaultStorageRoot) {
|
|
134
|
-
if (state.root.get(_key) == null) {
|
|
135
|
-
state.root.set(_key, state.defaultStorageRoot[_key]);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
function buildRootAndParentToChildren(items) {
|
|
141
|
-
var parentToChildren = new Map();
|
|
142
|
-
var root = null;
|
|
143
|
-
|
|
144
|
-
for (var _iterator2 = LiveObject._createForOfIteratorHelperLoose(items), _step2; !(_step2 = _iterator2()).done;) {
|
|
145
|
-
var tuple = _step2.value;
|
|
146
|
-
var parentId = tuple[1].parentId;
|
|
147
|
-
|
|
148
|
-
if (parentId == null) {
|
|
149
|
-
root = tuple;
|
|
150
|
-
} else {
|
|
151
|
-
var children = parentToChildren.get(parentId);
|
|
152
|
-
|
|
153
|
-
if (children != null) {
|
|
154
|
-
children.push(tuple);
|
|
155
|
-
} else {
|
|
156
|
-
parentToChildren.set(parentId, [tuple]);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
if (root == null) {
|
|
162
|
-
throw new Error("Root can't be null");
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
return [root, parentToChildren];
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
function updateRoot(items) {
|
|
169
|
-
if (!state.root) {
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
var currentItems = new Map();
|
|
174
|
-
state.items.forEach(function (liveCrdt, id) {
|
|
175
|
-
currentItems.set(id, liveCrdt._toSerializedCrdt());
|
|
176
|
-
});
|
|
177
|
-
var ops = LiveObject.getTreesDiffOperations(currentItems, new Map(items));
|
|
178
|
-
var result = apply(ops, false);
|
|
179
|
-
notify(result.updates);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
function load(items) {
|
|
183
|
-
var _buildRootAndParentTo = buildRootAndParentToChildren(items),
|
|
184
|
-
root = _buildRootAndParentTo[0],
|
|
185
|
-
parentToChildren = _buildRootAndParentTo[1];
|
|
186
|
-
|
|
187
|
-
return LiveObject.LiveObject._deserialize(root, parentToChildren, {
|
|
188
|
-
getItem: getItem,
|
|
189
|
-
addItem: addItem,
|
|
190
|
-
deleteItem: deleteItem,
|
|
191
|
-
generateId: generateId,
|
|
192
|
-
generateOpId: generateOpId,
|
|
193
|
-
dispatch: storageDispatch,
|
|
194
|
-
roomId: context.roomId
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
function addItem(id, item) {
|
|
199
|
-
state.items.set(id, item);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
function deleteItem(id) {
|
|
203
|
-
state.items.delete(id);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
function getItem(id) {
|
|
207
|
-
return state.items.get(id);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
function addToUndoStack(historyItem) {
|
|
211
|
-
if (state.undoStack.length >= 50) {
|
|
212
|
-
state.undoStack.shift();
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
if (state.isHistoryPaused) {
|
|
216
|
-
var _state$pausedHistory;
|
|
217
|
-
|
|
218
|
-
(_state$pausedHistory = state.pausedHistory).unshift.apply(_state$pausedHistory, historyItem);
|
|
219
|
-
} else {
|
|
220
|
-
state.undoStack.push(historyItem);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
function storageDispatch(ops, reverse, storageUpdates) {
|
|
225
|
-
if (state.isBatching) {
|
|
226
|
-
var _state$batch$ops, _state$batch$reverseO;
|
|
227
|
-
|
|
228
|
-
(_state$batch$ops = state.batch.ops).push.apply(_state$batch$ops, ops);
|
|
229
|
-
|
|
230
|
-
storageUpdates.forEach(function (value, key) {
|
|
231
|
-
state.batch.updates.storageUpdates.set(key, LiveObject.mergeStorageUpdates(state.batch.updates.storageUpdates.get(key), value));
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
(_state$batch$reverseO = state.batch.reverseOps).push.apply(_state$batch$reverseO, reverse);
|
|
235
|
-
} else {
|
|
236
|
-
addToUndoStack(reverse);
|
|
237
|
-
state.redoStack = [];
|
|
238
|
-
dispatch(ops);
|
|
239
|
-
notify({
|
|
240
|
-
storageUpdates: storageUpdates
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
function notify(_ref3) {
|
|
246
|
-
var _ref3$storageUpdates = _ref3.storageUpdates,
|
|
247
|
-
storageUpdates = _ref3$storageUpdates === void 0 ? new Map() : _ref3$storageUpdates,
|
|
248
|
-
_ref3$presence = _ref3.presence,
|
|
249
|
-
presence = _ref3$presence === void 0 ? false : _ref3$presence,
|
|
250
|
-
_ref3$others = _ref3.others,
|
|
251
|
-
otherEvents = _ref3$others === void 0 ? [] : _ref3$others;
|
|
252
|
-
|
|
253
|
-
if (otherEvents.length > 0) {
|
|
254
|
-
state.others = makeOthers(state.users);
|
|
255
|
-
|
|
256
|
-
for (var _iterator3 = LiveObject._createForOfIteratorHelperLoose(otherEvents), _step3; !(_step3 = _iterator3()).done;) {
|
|
257
|
-
var event = _step3.value;
|
|
258
|
-
|
|
259
|
-
for (var _iterator4 = LiveObject._createForOfIteratorHelperLoose(state.listeners.others), _step4; !(_step4 = _iterator4()).done;) {
|
|
260
|
-
var _listener = _step4.value;
|
|
261
|
-
|
|
262
|
-
_listener(state.others, event);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
if (presence) {
|
|
268
|
-
for (var _iterator5 = LiveObject._createForOfIteratorHelperLoose(state.listeners["my-presence"]), _step5; !(_step5 = _iterator5()).done;) {
|
|
269
|
-
var _listener2 = _step5.value;
|
|
270
|
-
|
|
271
|
-
_listener2(state.me);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
if (storageUpdates.size > 0) {
|
|
276
|
-
for (var _iterator6 = LiveObject._createForOfIteratorHelperLoose(state.listeners.storage), _step6; !(_step6 = _iterator6()).done;) {
|
|
277
|
-
var subscriber = _step6.value;
|
|
278
|
-
subscriber(Array.from(storageUpdates.values()));
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
function getConnectionId() {
|
|
284
|
-
if (state.connection.state === "open" || state.connection.state === "connecting") {
|
|
285
|
-
return state.connection.id;
|
|
286
|
-
} else if (state.lastConnectionId !== null) {
|
|
287
|
-
return state.lastConnectionId;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
throw new Error("Internal. Tried to get connection id but connection was never open");
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
function generateId() {
|
|
294
|
-
return getConnectionId() + ":" + state.clock++;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
function generateOpId() {
|
|
298
|
-
return getConnectionId() + ":" + state.opClock++;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
function apply(item, isLocal) {
|
|
302
|
-
var result = {
|
|
303
|
-
reverse: [],
|
|
304
|
-
updates: {
|
|
305
|
-
storageUpdates: new Map(),
|
|
306
|
-
presence: false
|
|
307
|
-
}
|
|
308
|
-
};
|
|
309
|
-
var createdNodeIds = new Set();
|
|
310
|
-
|
|
311
|
-
for (var _iterator7 = LiveObject._createForOfIteratorHelperLoose(item), _step7; !(_step7 = _iterator7()).done;) {
|
|
312
|
-
var op = _step7.value;
|
|
313
|
-
|
|
314
|
-
if (op.type === "presence") {
|
|
315
|
-
var reverse = {
|
|
316
|
-
type: "presence",
|
|
317
|
-
data: {}
|
|
318
|
-
};
|
|
319
|
-
|
|
320
|
-
for (var _key2 in op.data) {
|
|
321
|
-
reverse.data[_key2] = state.me[_key2];
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
state.me = LiveObject._extends({}, state.me, op.data);
|
|
325
|
-
|
|
326
|
-
if (state.buffer.presence == null) {
|
|
327
|
-
state.buffer.presence = op.data;
|
|
328
|
-
} else {
|
|
329
|
-
for (var _key3 in op.data) {
|
|
330
|
-
state.buffer.presence[_key3] = op.data[_key3];
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
result.reverse.unshift(reverse);
|
|
335
|
-
result.updates.presence = true;
|
|
336
|
-
} else {
|
|
337
|
-
if (isLocal && !op.opId) {
|
|
338
|
-
op.opId = generateOpId();
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
var applyOpResult = applyOp(op, isLocal);
|
|
342
|
-
|
|
343
|
-
if (applyOpResult.modified) {
|
|
344
|
-
var _applyOpResult$modifi;
|
|
345
|
-
|
|
346
|
-
var parentId = (_applyOpResult$modifi = applyOpResult.modified.node._parent) == null ? void 0 : _applyOpResult$modifi._id;
|
|
347
|
-
|
|
348
|
-
if (!createdNodeIds.has(parentId)) {
|
|
349
|
-
var _result$reverse;
|
|
350
|
-
|
|
351
|
-
result.updates.storageUpdates.set(applyOpResult.modified.node._id, LiveObject.mergeStorageUpdates(result.updates.storageUpdates.get(applyOpResult.modified.node._id), applyOpResult.modified));
|
|
352
|
-
|
|
353
|
-
(_result$reverse = result.reverse).unshift.apply(_result$reverse, applyOpResult.reverse);
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
if (op.type === LiveObject.OpType.CreateList || op.type === LiveObject.OpType.CreateMap || op.type === LiveObject.OpType.CreateObject) {
|
|
357
|
-
createdNodeIds.add(applyOpResult.modified.node._id);
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
return result;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
function applyOp(op, isLocal) {
|
|
367
|
-
if (op.opId) {
|
|
368
|
-
state.offlineOperations.delete(op.opId);
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
switch (op.type) {
|
|
372
|
-
case LiveObject.OpType.DeleteObjectKey:
|
|
373
|
-
case LiveObject.OpType.UpdateObject:
|
|
374
|
-
case LiveObject.OpType.DeleteCrdt:
|
|
375
|
-
{
|
|
376
|
-
var item = state.items.get(op.id);
|
|
377
|
-
|
|
378
|
-
if (item == null) {
|
|
379
|
-
return {
|
|
380
|
-
modified: false
|
|
381
|
-
};
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
return item._apply(op, isLocal);
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
case LiveObject.OpType.SetParentKey:
|
|
388
|
-
{
|
|
389
|
-
var _item = state.items.get(op.id);
|
|
390
|
-
|
|
391
|
-
if (_item == null) {
|
|
392
|
-
return {
|
|
393
|
-
modified: false
|
|
394
|
-
};
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
if (_item._parent instanceof LiveObject.LiveList) {
|
|
398
|
-
var previousKey = _item._parentKey;
|
|
399
|
-
|
|
400
|
-
if (previousKey === op.parentKey) {
|
|
401
|
-
return {
|
|
402
|
-
modified: false
|
|
403
|
-
};
|
|
404
|
-
} else {
|
|
405
|
-
return _item._parent._setChildKey(op.parentKey, _item, previousKey);
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
return {
|
|
410
|
-
modified: false
|
|
411
|
-
};
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
case LiveObject.OpType.CreateObject:
|
|
415
|
-
case LiveObject.OpType.CreateList:
|
|
416
|
-
case LiveObject.OpType.CreateMap:
|
|
417
|
-
case LiveObject.OpType.CreateRegister:
|
|
418
|
-
{
|
|
419
|
-
var parent = state.items.get(op.parentId);
|
|
420
|
-
|
|
421
|
-
if (parent == null) {
|
|
422
|
-
return {
|
|
423
|
-
modified: false
|
|
424
|
-
};
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
return parent._attachChild(op, isLocal);
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
function subscribe(firstParam, listener, options) {
|
|
433
|
-
if (firstParam instanceof LiveObject.AbstractCrdt) {
|
|
434
|
-
return crdtSubscribe(firstParam, listener, options);
|
|
435
|
-
} else if (typeof firstParam === "function") {
|
|
436
|
-
return genericSubscribe(firstParam);
|
|
437
|
-
} else if (!isValidRoomEventType(firstParam)) {
|
|
438
|
-
throw new Error("\"" + firstParam + "\" is not a valid event name");
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
state.listeners[firstParam].push(listener);
|
|
442
|
-
return function () {
|
|
443
|
-
var callbacks = state.listeners[firstParam];
|
|
444
|
-
LiveObject.remove(callbacks, listener);
|
|
445
|
-
};
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
function unsubscribe(event, callback) {
|
|
449
|
-
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");
|
|
450
|
-
|
|
451
|
-
if (!isValidRoomEventType(event)) {
|
|
452
|
-
throw new Error("\"" + event + "\" is not a valid event name");
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
var callbacks = state.listeners[event];
|
|
456
|
-
LiveObject.remove(callbacks, callback);
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
function getConnectionState() {
|
|
460
|
-
return state.connection.state;
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
function getSelf() {
|
|
464
|
-
return state.connection.state === "open" || state.connection.state === "connecting" ? {
|
|
465
|
-
connectionId: state.connection.id,
|
|
466
|
-
id: state.connection.userId,
|
|
467
|
-
info: state.connection.userInfo,
|
|
468
|
-
presence: getPresence()
|
|
469
|
-
} : null;
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
function connect() {
|
|
473
|
-
if (state.connection.state !== "closed" && state.connection.state !== "unavailable") {
|
|
474
|
-
return null;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
var auth = prepareAuthEndpoint(context.authentication, context.fetchPolyfill);
|
|
478
|
-
var createWebSocket = prepareCreateWebSocket(context.liveblocksServer, context.WebSocketPolyfill);
|
|
479
|
-
updateConnection({
|
|
480
|
-
state: "authenticating"
|
|
481
|
-
});
|
|
482
|
-
effects.authenticate(auth, createWebSocket);
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
function updatePresence(overrides, options) {
|
|
486
|
-
var oldValues = {};
|
|
487
|
-
|
|
488
|
-
if (state.buffer.presence == null) {
|
|
489
|
-
state.buffer.presence = {};
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
for (var _key4 in overrides) {
|
|
493
|
-
state.buffer.presence[_key4] = overrides[_key4];
|
|
494
|
-
oldValues[_key4] = state.me[_key4];
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
state.me = LiveObject._extends({}, state.me, overrides);
|
|
498
|
-
|
|
499
|
-
if (state.isBatching) {
|
|
500
|
-
if (options != null && options.addToHistory) {
|
|
501
|
-
state.batch.reverseOps.push({
|
|
502
|
-
type: "presence",
|
|
503
|
-
data: oldValues
|
|
504
|
-
});
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
state.batch.updates.presence = true;
|
|
508
|
-
} else {
|
|
509
|
-
tryFlushing();
|
|
510
|
-
|
|
511
|
-
if (options != null && options.addToHistory) {
|
|
512
|
-
addToUndoStack([{
|
|
513
|
-
type: "presence",
|
|
514
|
-
data: oldValues
|
|
515
|
-
}]);
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
notify({
|
|
519
|
-
presence: true
|
|
520
|
-
});
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
function authenticationSuccess(token, socket) {
|
|
525
|
-
socket.addEventListener("message", onMessage);
|
|
526
|
-
socket.addEventListener("open", onOpen);
|
|
527
|
-
socket.addEventListener("close", onClose);
|
|
528
|
-
socket.addEventListener("error", onError);
|
|
529
|
-
updateConnection({
|
|
530
|
-
state: "connecting",
|
|
531
|
-
id: token.actor,
|
|
532
|
-
userInfo: token.info,
|
|
533
|
-
userId: token.id
|
|
534
|
-
});
|
|
535
|
-
state.idFactory = makeIdFactory(token.actor);
|
|
536
|
-
state.socket = socket;
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
function authenticationFailure(error) {
|
|
540
|
-
if (process.env.NODE_ENV !== "production") {
|
|
541
|
-
console.error("Call to authentication endpoint failed", error);
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
state.token = null;
|
|
545
|
-
updateConnection({
|
|
31
|
+
var effects = mockedEffects || {
|
|
32
|
+
authenticate: function(auth, createWebSocket) {
|
|
33
|
+
var token = state.token;
|
|
34
|
+
if (!token || !LiveObject.isTokenValid(token)) return auth(context.roomId).then((function(_ref2) {
|
|
35
|
+
var token = _ref2.token;
|
|
36
|
+
"authenticating" === state.connection.state && (authenticationSuccess(parseToken(token), createWebSocket(token)),
|
|
37
|
+
state.token = token);
|
|
38
|
+
})).catch((function(er) {
|
|
39
|
+
return function(error) {
|
|
40
|
+
"production" !== process.env.NODE_ENV && console.error("Call to authentication endpoint failed", error);
|
|
41
|
+
state.token = null, updateConnection({
|
|
546
42
|
state: "unavailable"
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
function
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
43
|
+
}), state.numberOfRetry++, state.timeoutHandles.reconnect = effects.scheduleReconnect(getRetryDelay());
|
|
44
|
+
}(er);
|
|
45
|
+
}));
|
|
46
|
+
authenticationSuccess(parseToken(token), createWebSocket(token));
|
|
47
|
+
},
|
|
48
|
+
send: function(messageOrMessages) {
|
|
49
|
+
if (null == state.socket) throw new Error("Can't send message if socket is null");
|
|
50
|
+
state.socket.send(JSON.stringify(messageOrMessages));
|
|
51
|
+
},
|
|
52
|
+
delayFlush: function(delay) {
|
|
53
|
+
return setTimeout(tryFlushing, delay);
|
|
54
|
+
},
|
|
55
|
+
startHeartbeatInterval: function() {
|
|
56
|
+
return setInterval(heartbeat, 3e4);
|
|
57
|
+
},
|
|
58
|
+
schedulePongTimeout: function() {
|
|
59
|
+
return setTimeout(pongTimeout, 2e3);
|
|
60
|
+
},
|
|
61
|
+
scheduleReconnect: function(delay) {
|
|
62
|
+
return setTimeout(connect, delay);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
function genericSubscribe(callback) {
|
|
66
|
+
return state.listeners.storage.push(callback), function() {
|
|
67
|
+
return LiveObject.remove(state.listeners.storage, callback);
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function createOrUpdateRootFromMessage(message) {
|
|
71
|
+
if (0 === message.items.length) throw new Error("Internal error: cannot load storage without items");
|
|
72
|
+
var items, _buildRootAndParentTo, root, parentToChildren;
|
|
73
|
+
for (var _key in state.root ? function(items) {
|
|
74
|
+
if (!state.root) return;
|
|
75
|
+
var currentItems = new Map;
|
|
76
|
+
state.items.forEach((function(liveCrdt, id) {
|
|
77
|
+
currentItems.set(id, liveCrdt._toSerializedCrdt());
|
|
78
|
+
})), notify(apply(LiveObject.getTreesDiffOperations(currentItems, new Map(items)), !1).updates);
|
|
79
|
+
}(message.items) : state.root = (items = message.items, _buildRootAndParentTo = function(items) {
|
|
80
|
+
for (var _step2, parentToChildren = new Map, root = null, _iterator2 = LiveObject._createForOfIteratorHelperLoose(items); !(_step2 = _iterator2()).done; ) {
|
|
81
|
+
var tuple = _step2.value, parentId = tuple[1].parentId;
|
|
82
|
+
if (null == parentId) root = tuple; else {
|
|
83
|
+
var children = parentToChildren.get(parentId);
|
|
84
|
+
null != children ? children.push(tuple) : parentToChildren.set(parentId, [ tuple ]);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (null == root) throw new Error("Root can't be null");
|
|
88
|
+
return [ root, parentToChildren ];
|
|
89
|
+
}(items), root = _buildRootAndParentTo[0], parentToChildren = _buildRootAndParentTo[1],
|
|
90
|
+
LiveObject.LiveObject._deserialize(root, parentToChildren, {
|
|
91
|
+
getItem: getItem,
|
|
92
|
+
addItem: addItem,
|
|
93
|
+
deleteItem: deleteItem,
|
|
94
|
+
generateId: generateId,
|
|
95
|
+
generateOpId: generateOpId,
|
|
96
|
+
dispatch: storageDispatch,
|
|
97
|
+
roomId: context.roomId
|
|
98
|
+
})), state.defaultStorageRoot) null == state.root.get(_key) && state.root.set(_key, state.defaultStorageRoot[_key]);
|
|
99
|
+
}
|
|
100
|
+
function addItem(id, item) {
|
|
101
|
+
state.items.set(id, item);
|
|
102
|
+
}
|
|
103
|
+
function deleteItem(id) {
|
|
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: {}
|
|
620
162
|
};
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
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.OpType.CreateList && op.type !== LiveObject.OpType.CreateMap && op.type !== LiveObject.OpType.CreateObject || 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.OpType.DeleteObjectKey:
|
|
182
|
+
case LiveObject.OpType.UpdateObject:
|
|
183
|
+
case LiveObject.OpType.DeleteCrdt:
|
|
184
|
+
var item = state.items.get(op.id);
|
|
185
|
+
return null == item ? {
|
|
186
|
+
modified: !1
|
|
187
|
+
} : item._apply(op, isLocal);
|
|
188
|
+
|
|
189
|
+
case LiveObject.OpType.SetParentKey:
|
|
190
|
+
var _item = state.items.get(op.id);
|
|
191
|
+
if (null == _item) return {
|
|
192
|
+
modified: !1
|
|
193
|
+
};
|
|
194
|
+
if (_item._parent instanceof LiveObject.LiveList) {
|
|
195
|
+
var previousKey = _item._parentKey;
|
|
196
|
+
return previousKey === op.parentKey ? {
|
|
197
|
+
modified: !1
|
|
198
|
+
} : _item._parent._setChildKey(op.parentKey, _item, previousKey);
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
modified: !1
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
case LiveObject.OpType.CreateObject:
|
|
205
|
+
case LiveObject.OpType.CreateList:
|
|
206
|
+
case LiveObject.OpType.CreateMap:
|
|
207
|
+
case LiveObject.OpType.CreateRegister:
|
|
208
|
+
var parent = state.items.get(op.parentId);
|
|
209
|
+
return null == parent ? {
|
|
210
|
+
modified: !1
|
|
211
|
+
} : parent._attachChild(op, isLocal);
|
|
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
|
+
});
|
|
646
224
|
};
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
tryFlushing();
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
return {
|
|
658
|
-
type: "enter",
|
|
659
|
-
user: state.users[message.actor]
|
|
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
|
+
});
|
|
660
232
|
};
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
return
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
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.ClientMessageType.UpdatePresence,
|
|
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.parseJson(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.ServerMessageType.UserJoined:
|
|
338
|
+
updates.others.push(onUserJoinedMessage(message));
|
|
339
|
+
break;
|
|
340
|
+
|
|
341
|
+
case LiveObject.ServerMessageType.UpdatePresence:
|
|
342
|
+
var othersPresenceUpdate = onUpdatePresenceMessage(message);
|
|
343
|
+
othersPresenceUpdate && updates.others.push(othersPresenceUpdate);
|
|
344
|
+
break;
|
|
345
|
+
|
|
346
|
+
case LiveObject.ServerMessageType.Event:
|
|
347
|
+
onEvent(message);
|
|
348
|
+
break;
|
|
349
|
+
|
|
350
|
+
case LiveObject.ServerMessageType.UserLeft:
|
|
351
|
+
var _event2 = onUserLeftMessage(message);
|
|
352
|
+
_event2 && updates.others.push(_event2);
|
|
353
|
+
break;
|
|
354
|
+
|
|
355
|
+
case LiveObject.ServerMessageType.RoomState:
|
|
356
|
+
updates.others.push(onRoomStateMessage(message));
|
|
357
|
+
break;
|
|
358
|
+
|
|
359
|
+
case LiveObject.ServerMessageType.InitialStorageState:
|
|
360
|
+
var offlineOps = new Map(state.offlineOperations);
|
|
361
|
+
createOrUpdateRootFromMessage(message), applyAndSendOfflineOps(offlineOps), null == _getInitialStateResolver || _getInitialStateResolver();
|
|
362
|
+
break;
|
|
363
|
+
|
|
364
|
+
case LiveObject.ServerMessageType.UpdateStorage:
|
|
365
|
+
apply(message.ops, !1).updates.storageUpdates.forEach((function(value, key) {
|
|
366
|
+
updates.storageUpdates.set(key, LiveObject.mergeStorageUpdates(updates.storageUpdates.get(key), value));
|
|
679
367
|
}));
|
|
680
|
-
|
|
681
|
-
return LiveObject.compact([parseServerMessage(data)]);
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
function onMessage(event) {
|
|
686
|
-
if (event.data === "pong") {
|
|
687
|
-
clearTimeout(state.timeoutHandles.pongTimeout);
|
|
688
|
-
return;
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
var messages = parseServerMessages(event.data);
|
|
692
|
-
|
|
693
|
-
if (messages === null || messages.length === 0) {
|
|
694
|
-
return;
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
var updates = {
|
|
698
|
-
storageUpdates: new Map(),
|
|
699
|
-
others: []
|
|
700
|
-
};
|
|
701
|
-
|
|
702
|
-
for (var _iterator9 = LiveObject._createForOfIteratorHelperLoose(messages), _step9; !(_step9 = _iterator9()).done;) {
|
|
703
|
-
var message = _step9.value;
|
|
704
|
-
|
|
705
|
-
switch (message.type) {
|
|
706
|
-
case LiveObject.ServerMessageType.UserJoined:
|
|
707
|
-
{
|
|
708
|
-
updates.others.push(onUserJoinedMessage(message));
|
|
709
|
-
break;
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
case LiveObject.ServerMessageType.UpdatePresence:
|
|
713
|
-
{
|
|
714
|
-
var othersPresenceUpdate = onUpdatePresenceMessage(message);
|
|
715
|
-
|
|
716
|
-
if (othersPresenceUpdate) {
|
|
717
|
-
updates.others.push(othersPresenceUpdate);
|
|
718
|
-
}
|
|
719
|
-
|
|
720
|
-
break;
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
case LiveObject.ServerMessageType.Event:
|
|
724
|
-
{
|
|
725
|
-
onEvent(message);
|
|
726
|
-
break;
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
case LiveObject.ServerMessageType.UserLeft:
|
|
730
|
-
{
|
|
731
|
-
var _event = onUserLeftMessage(message);
|
|
732
|
-
|
|
733
|
-
if (_event) {
|
|
734
|
-
updates.others.push(_event);
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
break;
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
case LiveObject.ServerMessageType.RoomState:
|
|
741
|
-
{
|
|
742
|
-
updates.others.push(onRoomStateMessage(message));
|
|
743
|
-
break;
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
case LiveObject.ServerMessageType.InitialStorageState:
|
|
747
|
-
{
|
|
748
|
-
var offlineOps = new Map(state.offlineOperations);
|
|
749
|
-
createOrUpdateRootFromMessage(message);
|
|
750
|
-
applyAndSendOfflineOps(offlineOps);
|
|
751
|
-
_getInitialStateResolver == null ? void 0 : _getInitialStateResolver();
|
|
752
|
-
break;
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
case LiveObject.ServerMessageType.UpdateStorage:
|
|
756
|
-
{
|
|
757
|
-
var applyResult = apply(message.ops, false);
|
|
758
|
-
applyResult.updates.storageUpdates.forEach(function (value, key) {
|
|
759
|
-
updates.storageUpdates.set(key, LiveObject.mergeStorageUpdates(updates.storageUpdates.get(key), value));
|
|
760
|
-
});
|
|
761
|
-
break;
|
|
762
|
-
}
|
|
763
|
-
}
|
|
368
|
+
}
|
|
764
369
|
}
|
|
765
|
-
|
|
766
370
|
notify(updates);
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
state
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
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
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
}));
|
|
862
|
-
state.numberOfRetry = 0;
|
|
863
|
-
|
|
864
|
-
if (state.lastConnectionId !== undefined) {
|
|
865
|
-
state.buffer.presence = state.me;
|
|
866
|
-
tryFlushing();
|
|
867
|
-
}
|
|
868
|
-
|
|
869
|
-
state.lastConnectionId = state.connection.id;
|
|
870
|
-
|
|
871
|
-
if (state.root) {
|
|
872
|
-
state.buffer.messages.push({
|
|
873
|
-
type: LiveObject.ClientMessageType.FetchStorage
|
|
874
|
-
});
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
tryFlushing();
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
function heartbeat() {
|
|
882
|
-
if (state.socket == null) {
|
|
883
|
-
return;
|
|
884
|
-
}
|
|
885
|
-
|
|
886
|
-
clearTimeout(state.timeoutHandles.pongTimeout);
|
|
887
|
-
state.timeoutHandles.pongTimeout = effects.schedulePongTimeout();
|
|
888
|
-
|
|
889
|
-
if (state.socket.readyState === state.socket.OPEN) {
|
|
890
|
-
state.socket.send("ping");
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
|
|
894
|
-
function pongTimeout() {
|
|
895
|
-
reconnect();
|
|
896
|
-
}
|
|
897
|
-
|
|
898
|
-
function reconnect() {
|
|
899
|
-
if (state.socket) {
|
|
900
|
-
state.socket.removeEventListener("open", onOpen);
|
|
901
|
-
state.socket.removeEventListener("message", onMessage);
|
|
902
|
-
state.socket.removeEventListener("close", onClose);
|
|
903
|
-
state.socket.removeEventListener("error", onError);
|
|
904
|
-
state.socket.close();
|
|
905
|
-
state.socket = null;
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
updateConnection({
|
|
909
|
-
state: "unavailable"
|
|
910
|
-
});
|
|
911
|
-
clearTimeout(state.timeoutHandles.pongTimeout);
|
|
912
|
-
|
|
913
|
-
if (state.timeoutHandles.flush) {
|
|
914
|
-
clearTimeout(state.timeoutHandles.flush);
|
|
915
|
-
}
|
|
916
|
-
|
|
917
|
-
clearTimeout(state.timeoutHandles.reconnect);
|
|
918
|
-
clearInterval(state.intervalHandles.heartbeat);
|
|
919
|
-
connect();
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
function applyAndSendOfflineOps(offlineOps) {
|
|
923
|
-
if (offlineOps.size === 0) {
|
|
924
|
-
return;
|
|
925
|
-
}
|
|
926
|
-
|
|
927
|
-
var messages = [];
|
|
928
|
-
var ops = Array.from(offlineOps.values());
|
|
929
|
-
var result = apply(ops, true);
|
|
930
|
-
messages.push({
|
|
371
|
+
}
|
|
372
|
+
} else clearTimeout(state.timeoutHandles.pongTimeout);
|
|
373
|
+
}
|
|
374
|
+
function onClose(event) {
|
|
375
|
+
if (state.socket = null, clearTimeout(state.timeoutHandles.pongTimeout), clearInterval(state.intervalHandles.heartbeat),
|
|
376
|
+
state.timeoutHandles.flush && clearTimeout(state.timeoutHandles.flush), clearTimeout(state.timeoutHandles.reconnect),
|
|
377
|
+
state.users = {}, notify({
|
|
378
|
+
others: [ {
|
|
379
|
+
type: "reset"
|
|
380
|
+
} ]
|
|
381
|
+
}), event.code >= 4e3 && event.code <= 4100) {
|
|
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.ClientMessageType.FetchStorage
|
|
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.ClientMessageType.UpdateStorage,
|
|
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.ClientMessageType.UpdatePresence,
|
|
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({
|
|
931
465
|
type: LiveObject.ClientMessageType.UpdateStorage,
|
|
932
|
-
ops:
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
function
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
(_state$buffer$storage = state.buffer.storageOperations).push.apply(_state$buffer$storage, ops);
|
|
1069
|
-
|
|
1070
|
-
tryFlushing();
|
|
1071
|
-
}
|
|
1072
|
-
|
|
1073
|
-
var _getInitialStatePromise = null;
|
|
1074
|
-
var _getInitialStateResolver = null;
|
|
1075
|
-
|
|
1076
|
-
function getStorage() {
|
|
1077
|
-
if (state.root) {
|
|
1078
|
-
return new Promise(function (resolve) {
|
|
1079
|
-
return resolve({
|
|
1080
|
-
root: state.root
|
|
1081
|
-
});
|
|
1082
|
-
});
|
|
1083
|
-
}
|
|
1084
|
-
|
|
1085
|
-
if (_getInitialStatePromise == null) {
|
|
1086
|
-
state.buffer.messages.push({
|
|
1087
|
-
type: LiveObject.ClientMessageType.FetchStorage
|
|
1088
|
-
});
|
|
1089
|
-
tryFlushing();
|
|
1090
|
-
_getInitialStatePromise = new Promise(function (resolve) {
|
|
1091
|
-
return _getInitialStateResolver = resolve;
|
|
1092
|
-
});
|
|
1093
|
-
}
|
|
1094
|
-
|
|
1095
|
-
return _getInitialStatePromise.then(function () {
|
|
1096
|
-
return {
|
|
1097
|
-
root: state.root
|
|
1098
|
-
};
|
|
1099
|
-
});
|
|
1100
|
-
}
|
|
1101
|
-
|
|
1102
|
-
function undo() {
|
|
1103
|
-
if (state.isBatching) {
|
|
1104
|
-
throw new Error("undo is not allowed during a batch");
|
|
1105
|
-
}
|
|
1106
|
-
|
|
1107
|
-
var historyItem = state.undoStack.pop();
|
|
1108
|
-
|
|
1109
|
-
if (historyItem == null) {
|
|
1110
|
-
return;
|
|
1111
|
-
}
|
|
1112
|
-
|
|
1113
|
-
state.isHistoryPaused = false;
|
|
1114
|
-
var result = apply(historyItem, true);
|
|
1115
|
-
notify(result.updates);
|
|
1116
|
-
state.redoStack.push(result.reverse);
|
|
1117
|
-
|
|
1118
|
-
for (var _iterator13 = LiveObject._createForOfIteratorHelperLoose(historyItem), _step13; !(_step13 = _iterator13()).done;) {
|
|
1119
|
-
var op = _step13.value;
|
|
1120
|
-
|
|
1121
|
-
if (op.type !== "presence") {
|
|
1122
|
-
state.buffer.storageOperations.push(op);
|
|
1123
|
-
}
|
|
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.ClientMessageType.ClientEvent,
|
|
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);
|
|
1124
602
|
}
|
|
1125
|
-
|
|
1126
603
|
tryFlushing();
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
function
|
|
1130
|
-
|
|
1131
|
-
|
|
604
|
+
}
|
|
605
|
+
},
|
|
606
|
+
redo: function() {
|
|
607
|
+
if (state.isBatching) throw new Error("redo is not allowed during a batch");
|
|
608
|
+
var historyItem = state.redoStack.pop();
|
|
609
|
+
if (null != historyItem) {
|
|
610
|
+
state.isHistoryPaused = !1;
|
|
611
|
+
var result = apply(historyItem, !0);
|
|
612
|
+
notify(result.updates), state.undoStack.push(result.reverse);
|
|
613
|
+
for (var _step14, _iterator14 = LiveObject._createForOfIteratorHelperLoose(historyItem); !(_step14 = _iterator14()).done; ) {
|
|
614
|
+
var op = _step14.value;
|
|
615
|
+
"presence" !== op.type && state.buffer.storageOperations.push(op);
|
|
1132
616
|
}
|
|
1133
|
-
|
|
1134
|
-
var historyItem = state.redoStack.pop();
|
|
1135
|
-
|
|
1136
|
-
if (historyItem == null) {
|
|
1137
|
-
return;
|
|
1138
|
-
}
|
|
1139
|
-
|
|
1140
|
-
state.isHistoryPaused = false;
|
|
1141
|
-
var result = apply(historyItem, true);
|
|
1142
|
-
notify(result.updates);
|
|
1143
|
-
state.undoStack.push(result.reverse);
|
|
1144
|
-
|
|
1145
|
-
for (var _iterator14 = LiveObject._createForOfIteratorHelperLoose(historyItem), _step14; !(_step14 = _iterator14()).done;) {
|
|
1146
|
-
var op = _step14.value;
|
|
1147
|
-
|
|
1148
|
-
if (op.type !== "presence") {
|
|
1149
|
-
state.buffer.storageOperations.push(op);
|
|
1150
|
-
}
|
|
1151
|
-
}
|
|
1152
|
-
|
|
1153
617
|
tryFlushing();
|
|
618
|
+
}
|
|
619
|
+
},
|
|
620
|
+
pauseHistory: function() {
|
|
621
|
+
state.pausedHistory = [], state.isHistoryPaused = !0;
|
|
622
|
+
},
|
|
623
|
+
resumeHistory: function() {
|
|
624
|
+
state.isHistoryPaused = !1, state.pausedHistory.length > 0 && addToUndoStack(state.pausedHistory),
|
|
625
|
+
state.pausedHistory = [];
|
|
626
|
+
},
|
|
627
|
+
getStorage: function() {
|
|
628
|
+
return state.root ? new Promise((function(resolve) {
|
|
629
|
+
return resolve({
|
|
630
|
+
root: state.root
|
|
631
|
+
});
|
|
632
|
+
})) : (null == _getInitialStatePromise && (state.buffer.messages.push({
|
|
633
|
+
type: LiveObject.ClientMessageType.FetchStorage
|
|
634
|
+
}), tryFlushing(), _getInitialStatePromise = new Promise((function(resolve) {
|
|
635
|
+
return _getInitialStateResolver = resolve;
|
|
636
|
+
}))), _getInitialStatePromise.then((function() {
|
|
637
|
+
return {
|
|
638
|
+
root: state.root
|
|
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
|
+
}
|
|
1154
658
|
}
|
|
1155
|
-
|
|
1156
|
-
function batch(callback) {
|
|
1157
|
-
if (state.isBatching) {
|
|
1158
|
-
throw new Error("batch should not be called during a batch");
|
|
1159
|
-
}
|
|
1160
|
-
|
|
1161
|
-
state.isBatching = true;
|
|
1162
|
-
|
|
1163
|
-
try {
|
|
1164
|
-
callback();
|
|
1165
|
-
} finally {
|
|
1166
|
-
state.isBatching = false;
|
|
1167
|
-
|
|
1168
|
-
if (state.batch.reverseOps.length > 0) {
|
|
1169
|
-
addToUndoStack(state.batch.reverseOps);
|
|
1170
|
-
}
|
|
1171
|
-
|
|
1172
|
-
if (state.batch.ops.length > 0) {
|
|
1173
|
-
state.redoStack = [];
|
|
1174
|
-
}
|
|
1175
|
-
|
|
1176
|
-
if (state.batch.ops.length > 0) {
|
|
1177
|
-
dispatch(state.batch.ops);
|
|
1178
|
-
}
|
|
1179
|
-
|
|
1180
|
-
notify(state.batch.updates);
|
|
1181
|
-
state.batch = {
|
|
1182
|
-
ops: [],
|
|
1183
|
-
reverseOps: [],
|
|
1184
|
-
updates: {
|
|
1185
|
-
others: [],
|
|
1186
|
-
storageUpdates: new Map(),
|
|
1187
|
-
presence: false
|
|
1188
|
-
}
|
|
1189
|
-
};
|
|
1190
|
-
tryFlushing();
|
|
1191
|
-
}
|
|
1192
|
-
}
|
|
1193
|
-
|
|
1194
|
-
function pauseHistory() {
|
|
1195
|
-
state.pausedHistory = [];
|
|
1196
|
-
state.isHistoryPaused = true;
|
|
1197
|
-
}
|
|
1198
|
-
|
|
1199
|
-
function resumeHistory() {
|
|
1200
|
-
state.isHistoryPaused = false;
|
|
1201
|
-
|
|
1202
|
-
if (state.pausedHistory.length > 0) {
|
|
1203
|
-
addToUndoStack(state.pausedHistory);
|
|
1204
|
-
}
|
|
1205
|
-
|
|
1206
|
-
state.pausedHistory = [];
|
|
1207
|
-
}
|
|
1208
|
-
|
|
1209
|
-
function simulateSocketClose() {
|
|
1210
|
-
if (state.socket) {
|
|
1211
|
-
state.socket.close();
|
|
1212
|
-
}
|
|
1213
|
-
}
|
|
1214
|
-
|
|
1215
|
-
function simulateSendCloseEvent(event) {
|
|
1216
|
-
if (state.socket) {
|
|
1217
|
-
onClose(event);
|
|
1218
|
-
}
|
|
1219
|
-
}
|
|
1220
|
-
|
|
1221
|
-
return {
|
|
1222
|
-
onClose: onClose,
|
|
1223
|
-
onMessage: onMessage,
|
|
1224
|
-
authenticationSuccess: authenticationSuccess,
|
|
1225
|
-
heartbeat: heartbeat,
|
|
1226
|
-
onNavigatorOnline: onNavigatorOnline,
|
|
1227
|
-
simulateSocketClose: simulateSocketClose,
|
|
1228
|
-
simulateSendCloseEvent: simulateSendCloseEvent,
|
|
1229
|
-
onVisibilityChange: onVisibilityChange,
|
|
1230
|
-
getUndoStack: function getUndoStack() {
|
|
1231
|
-
return state.undoStack;
|
|
1232
|
-
},
|
|
1233
|
-
getItemsCount: function getItemsCount() {
|
|
1234
|
-
return state.items.size;
|
|
1235
|
-
},
|
|
1236
|
-
connect: connect,
|
|
1237
|
-
disconnect: disconnect,
|
|
1238
|
-
subscribe: subscribe,
|
|
1239
|
-
unsubscribe: unsubscribe,
|
|
1240
|
-
updatePresence: updatePresence,
|
|
1241
|
-
broadcastEvent: broadcastEvent,
|
|
1242
|
-
batch: batch,
|
|
1243
|
-
undo: undo,
|
|
1244
|
-
redo: redo,
|
|
1245
|
-
pauseHistory: pauseHistory,
|
|
1246
|
-
resumeHistory: resumeHistory,
|
|
1247
|
-
getStorage: getStorage,
|
|
1248
|
-
selectors: {
|
|
1249
|
-
getConnectionState: getConnectionState,
|
|
1250
|
-
getSelf: getSelf,
|
|
1251
|
-
getPresence: getPresence,
|
|
1252
|
-
getOthers: getOthers
|
|
1253
|
-
}
|
|
1254
|
-
};
|
|
1255
|
-
}
|
|
1256
|
-
function defaultState(initialPresence, initialStorage) {
|
|
1257
|
-
return {
|
|
1258
|
-
connection: {
|
|
1259
|
-
state: "closed"
|
|
1260
|
-
},
|
|
1261
|
-
token: null,
|
|
1262
|
-
lastConnectionId: null,
|
|
1263
|
-
socket: null,
|
|
1264
|
-
listeners: {
|
|
1265
|
-
event: [],
|
|
1266
|
-
others: [],
|
|
1267
|
-
"my-presence": [],
|
|
1268
|
-
error: [],
|
|
1269
|
-
connection: [],
|
|
1270
|
-
storage: []
|
|
1271
|
-
},
|
|
1272
|
-
numberOfRetry: 0,
|
|
1273
|
-
lastFlushTime: 0,
|
|
1274
|
-
timeoutHandles: {
|
|
1275
|
-
flush: null,
|
|
1276
|
-
reconnect: 0,
|
|
1277
|
-
pongTimeout: 0
|
|
1278
|
-
},
|
|
1279
|
-
buffer: {
|
|
1280
|
-
presence: initialPresence == null ? {} : initialPresence,
|
|
1281
|
-
messages: [],
|
|
1282
|
-
storageOperations: []
|
|
1283
|
-
},
|
|
1284
|
-
intervalHandles: {
|
|
1285
|
-
heartbeat: 0
|
|
1286
|
-
},
|
|
1287
|
-
me: initialPresence == null ? {} : initialPresence,
|
|
1288
|
-
users: {},
|
|
1289
|
-
others: makeOthers({}),
|
|
1290
|
-
defaultStorageRoot: initialStorage,
|
|
1291
|
-
idFactory: null,
|
|
1292
|
-
clock: 0,
|
|
1293
|
-
opClock: 0,
|
|
1294
|
-
items: new Map(),
|
|
1295
|
-
root: undefined,
|
|
1296
|
-
undoStack: [],
|
|
1297
|
-
redoStack: [],
|
|
1298
|
-
isHistoryPaused: false,
|
|
1299
|
-
pausedHistory: [],
|
|
1300
|
-
isBatching: false,
|
|
1301
|
-
batch: {
|
|
1302
|
-
ops: [],
|
|
1303
|
-
updates: {
|
|
1304
|
-
storageUpdates: new Map(),
|
|
1305
|
-
presence: false,
|
|
1306
|
-
others: []
|
|
1307
|
-
},
|
|
1308
|
-
reverseOps: []
|
|
1309
|
-
},
|
|
1310
|
-
offlineOperations: new Map()
|
|
1311
|
-
};
|
|
659
|
+
};
|
|
1312
660
|
}
|
|
1313
|
-
function createRoom(options, context) {
|
|
1314
|
-
var _options$initialPrese, _options$initialStora;
|
|
1315
661
|
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
var state = defaultState(typeof initialPresence === "function" ? initialPresence(context.roomId) : initialPresence, typeof initialStorage === "function" ? initialStorage(context.roomId) : initialStorage);
|
|
1319
|
-
var machine = makeStateMachine(state, context);
|
|
1320
|
-
var room = {
|
|
1321
|
-
id: context.roomId,
|
|
1322
|
-
getConnectionState: machine.selectors.getConnectionState,
|
|
1323
|
-
getSelf: machine.selectors.getSelf,
|
|
1324
|
-
subscribe: machine.subscribe,
|
|
1325
|
-
unsubscribe: machine.unsubscribe,
|
|
1326
|
-
getPresence: machine.selectors.getPresence,
|
|
1327
|
-
updatePresence: machine.updatePresence,
|
|
1328
|
-
getOthers: machine.selectors.getOthers,
|
|
1329
|
-
broadcastEvent: machine.broadcastEvent,
|
|
1330
|
-
getStorage: machine.getStorage,
|
|
1331
|
-
batch: machine.batch,
|
|
1332
|
-
history: {
|
|
1333
|
-
undo: machine.undo,
|
|
1334
|
-
redo: machine.redo,
|
|
1335
|
-
pause: machine.pauseHistory,
|
|
1336
|
-
resume: machine.resumeHistory
|
|
1337
|
-
},
|
|
1338
|
-
internalDevTools: {
|
|
1339
|
-
closeWebsocket: machine.simulateSocketClose,
|
|
1340
|
-
sendCloseEvent: machine.simulateSendCloseEvent
|
|
1341
|
-
}
|
|
1342
|
-
};
|
|
662
|
+
function createRoom(options, context) {
|
|
663
|
+
var _options$initialPrese, _options$initialStora, initialPresence = null != (_options$initialPrese = options.initialPresence) ? _options$initialPrese : options.defaultPresence, initialStorage = null != (_options$initialStora = options.initialStorage) ? _options$initialStora : options.defaultStorageRoot, machine = makeStateMachine(function(initialPresence, initialStorage) {
|
|
1343
664
|
return {
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
665
|
+
connection: {
|
|
666
|
+
state: "closed"
|
|
667
|
+
},
|
|
668
|
+
token: null,
|
|
669
|
+
lastConnectionId: null,
|
|
670
|
+
socket: null,
|
|
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: []
|
|
714
|
+
},
|
|
715
|
+
reverseOps: []
|
|
716
|
+
},
|
|
717
|
+
offlineOperations: new Map
|
|
1349
718
|
};
|
|
719
|
+
}("function" == typeof initialPresence ? initialPresence(context.roomId) : initialPresence, "function" == typeof initialStorage ? initialStorage(context.roomId) : initialStorage), context), room = {
|
|
720
|
+
id: context.roomId,
|
|
721
|
+
getConnectionState: machine.selectors.getConnectionState,
|
|
722
|
+
getSelf: machine.selectors.getSelf,
|
|
723
|
+
subscribe: machine.subscribe,
|
|
724
|
+
unsubscribe: machine.unsubscribe,
|
|
725
|
+
getPresence: machine.selectors.getPresence,
|
|
726
|
+
updatePresence: machine.updatePresence,
|
|
727
|
+
getOthers: machine.selectors.getOthers,
|
|
728
|
+
broadcastEvent: machine.broadcastEvent,
|
|
729
|
+
getStorage: machine.getStorage,
|
|
730
|
+
batch: machine.batch,
|
|
731
|
+
history: {
|
|
732
|
+
undo: machine.undo,
|
|
733
|
+
redo: machine.redo,
|
|
734
|
+
pause: machine.pauseHistory,
|
|
735
|
+
resume: machine.resumeHistory
|
|
736
|
+
},
|
|
737
|
+
internalDevTools: {
|
|
738
|
+
closeWebsocket: machine.simulateSocketClose,
|
|
739
|
+
sendCloseEvent: machine.simulateSendCloseEvent
|
|
740
|
+
}
|
|
741
|
+
};
|
|
742
|
+
return {
|
|
743
|
+
connect: machine.connect,
|
|
744
|
+
disconnect: machine.disconnect,
|
|
745
|
+
onNavigatorOnline: machine.onNavigatorOnline,
|
|
746
|
+
onVisibilityChange: machine.onVisibilityChange,
|
|
747
|
+
room: room
|
|
748
|
+
};
|
|
1350
749
|
}
|
|
1351
750
|
|
|
1352
|
-
var LiveblocksError = function
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
_this = _Error.call(this, message) || this;
|
|
1359
|
-
_this.code = code;
|
|
1360
|
-
return _this;
|
|
1361
|
-
}
|
|
1362
|
-
|
|
1363
|
-
return LiveblocksError;
|
|
751
|
+
var LiveblocksError = function(_Error) {
|
|
752
|
+
function LiveblocksError(message, code) {
|
|
753
|
+
return _Error.call(this, message) || this;
|
|
754
|
+
}
|
|
755
|
+
return LiveObject._inheritsLoose(LiveblocksError, _Error), LiveblocksError;
|
|
1364
756
|
}(LiveObject._wrapNativeSuper(Error));
|
|
1365
757
|
|
|
1366
758
|
function parseToken(token) {
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
return {
|
|
1377
|
-
actor: data.actor,
|
|
1378
|
-
id: data.id,
|
|
1379
|
-
info: data.info
|
|
1380
|
-
};
|
|
1381
|
-
}
|
|
1382
|
-
|
|
1383
|
-
throw new Error("Authentication error. Liveblocks could not parse the response of your authentication endpoint");
|
|
1384
|
-
}
|
|
1385
|
-
|
|
1386
|
-
function prepareCreateWebSocket(liveblocksServer, WebSocketPolyfill) {
|
|
1387
|
-
if (typeof window === "undefined" && WebSocketPolyfill == null) {
|
|
1388
|
-
throw new Error("To use Liveblocks client in a non-dom environment, you need to provide a WebSocket polyfill.");
|
|
1389
|
-
}
|
|
1390
|
-
|
|
1391
|
-
var ws = WebSocketPolyfill || WebSocket;
|
|
1392
|
-
return function (token) {
|
|
1393
|
-
return new ws(liveblocksServer + "/?token=" + token);
|
|
1394
|
-
};
|
|
1395
|
-
}
|
|
1396
|
-
|
|
1397
|
-
function prepareAuthEndpoint(authentication, fetchPolyfill) {
|
|
1398
|
-
if (authentication.type === "public") {
|
|
1399
|
-
if (typeof window === "undefined" && fetchPolyfill == null) {
|
|
1400
|
-
throw new Error("To use Liveblocks client in a non-dom environment with a publicApiKey, you need to provide a fetch polyfill.");
|
|
1401
|
-
}
|
|
1402
|
-
|
|
1403
|
-
return function (room) {
|
|
1404
|
-
return fetchAuthEndpoint(fetchPolyfill || fetch, authentication.url, {
|
|
1405
|
-
room: room,
|
|
1406
|
-
publicApiKey: authentication.publicApiKey
|
|
1407
|
-
});
|
|
1408
|
-
};
|
|
1409
|
-
}
|
|
1410
|
-
|
|
1411
|
-
if (authentication.type === "private") {
|
|
1412
|
-
if (typeof window === "undefined" && fetchPolyfill == null) {
|
|
1413
|
-
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.");
|
|
1414
|
-
}
|
|
1415
|
-
|
|
1416
|
-
return function (room) {
|
|
1417
|
-
return fetchAuthEndpoint(fetchPolyfill || fetch, authentication.url, {
|
|
1418
|
-
room: room
|
|
1419
|
-
});
|
|
1420
|
-
};
|
|
1421
|
-
}
|
|
1422
|
-
|
|
1423
|
-
if (authentication.type === "custom") {
|
|
1424
|
-
return authentication.callback;
|
|
1425
|
-
}
|
|
1426
|
-
|
|
1427
|
-
throw new Error("Internal error. Unexpected authentication type");
|
|
759
|
+
var tokenParts = token.split(".");
|
|
760
|
+
if (3 !== tokenParts.length) throw new Error("Authentication error. Liveblocks could not parse the response of your authentication endpoint");
|
|
761
|
+
var data = LiveObject.parseJson(atob(tokenParts[1]));
|
|
762
|
+
if (void 0 !== data && LiveObject.isJsonObject(data) && "number" == typeof data.actor && (void 0 === data.id || "string" == typeof data.id)) return {
|
|
763
|
+
actor: data.actor,
|
|
764
|
+
id: data.id,
|
|
765
|
+
info: data.info
|
|
766
|
+
};
|
|
767
|
+
throw new Error("Authentication error. Liveblocks could not parse the response of your authentication endpoint");
|
|
1428
768
|
}
|
|
1429
769
|
|
|
1430
770
|
function fetchAuthEndpoint(fetch, endpoint, body) {
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
if (typeof authResponse.token !== "string") {
|
|
1447
|
-
throw new AuthenticationError("Expected a json with a string token when doing a POST request on \"" + endpoint + "\", but got " + JSON.stringify(authResponse));
|
|
1448
|
-
}
|
|
1449
|
-
|
|
1450
|
-
return authResponse;
|
|
1451
|
-
});
|
|
771
|
+
return fetch(endpoint, {
|
|
772
|
+
method: "POST",
|
|
773
|
+
headers: {
|
|
774
|
+
"Content-Type": "application/json"
|
|
775
|
+
},
|
|
776
|
+
body: JSON.stringify(body)
|
|
777
|
+
}).then((function(res) {
|
|
778
|
+
if (!res.ok) throw new AuthenticationError("Expected a status 200 but got " + res.status + ' when doing a POST request on "' + endpoint + '"');
|
|
779
|
+
return res.json().catch((function(er) {
|
|
780
|
+
throw new AuthenticationError('Expected a json when doing a POST request on "' + endpoint + '". ' + er);
|
|
781
|
+
}));
|
|
782
|
+
})).then((function(authResponse) {
|
|
783
|
+
if ("string" != typeof authResponse.token) throw new AuthenticationError('Expected a json with a string token when doing a POST request on "' + endpoint + '", but got ' + JSON.stringify(authResponse));
|
|
784
|
+
return authResponse;
|
|
785
|
+
}));
|
|
1452
786
|
}
|
|
1453
787
|
|
|
1454
|
-
var AuthenticationError = function
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
}
|
|
1460
|
-
|
|
1461
|
-
return AuthenticationError;
|
|
788
|
+
var AuthenticationError = function(_Error2) {
|
|
789
|
+
function AuthenticationError(message) {
|
|
790
|
+
return _Error2.call(this, message) || this;
|
|
791
|
+
}
|
|
792
|
+
return LiveObject._inheritsLoose(AuthenticationError, _Error2), AuthenticationError;
|
|
1462
793
|
}(LiveObject._wrapNativeSuper(Error));
|
|
1463
794
|
|
|
1464
|
-
function createClient(options) {
|
|
1465
|
-
var clientOptions = options;
|
|
1466
|
-
var throttleDelay = getThrottleDelayFromOptions(options);
|
|
1467
|
-
var rooms = new Map();
|
|
1468
|
-
|
|
1469
|
-
function getRoom(roomId) {
|
|
1470
|
-
var internalRoom = rooms.get(roomId);
|
|
1471
|
-
return internalRoom ? internalRoom.room : null;
|
|
1472
|
-
}
|
|
1473
|
-
|
|
1474
|
-
function enter(roomId, options) {
|
|
1475
|
-
if (options === void 0) {
|
|
1476
|
-
options = {};
|
|
1477
|
-
}
|
|
1478
|
-
|
|
1479
|
-
var internalRoom = rooms.get(roomId);
|
|
1480
|
-
|
|
1481
|
-
if (internalRoom) {
|
|
1482
|
-
return internalRoom.room;
|
|
1483
|
-
}
|
|
1484
|
-
|
|
1485
|
-
LiveObject.deprecateIf(options.defaultPresence, "Argument `defaultPresence` will be removed in @liveblocks/client 0.18. Please use `initialPresence` instead. For more info, see https://bit.ly/3Niy5aP", "defaultPresence");
|
|
1486
|
-
LiveObject.deprecateIf(options.defaultStorageRoot, "Argument `defaultStorageRoot` will be removed in @liveblocks/client 0.18. Please use `initialStorage` instead. For more info, see https://bit.ly/3Niy5aP", "defaultStorageRoot");
|
|
1487
|
-
internalRoom = createRoom({
|
|
1488
|
-
initialPresence: options.initialPresence,
|
|
1489
|
-
initialStorage: options.initialStorage,
|
|
1490
|
-
defaultPresence: options.defaultPresence,
|
|
1491
|
-
defaultStorageRoot: options.defaultStorageRoot
|
|
1492
|
-
}, {
|
|
1493
|
-
roomId: roomId,
|
|
1494
|
-
throttleDelay: throttleDelay,
|
|
1495
|
-
WebSocketPolyfill: clientOptions.WebSocketPolyfill,
|
|
1496
|
-
fetchPolyfill: clientOptions.fetchPolyfill,
|
|
1497
|
-
liveblocksServer: clientOptions.liveblocksServer || "wss://liveblocks.net/v5",
|
|
1498
|
-
authentication: prepareAuthentication(clientOptions)
|
|
1499
|
-
});
|
|
1500
|
-
rooms.set(roomId, internalRoom);
|
|
1501
|
-
|
|
1502
|
-
if (!options.DO_NOT_USE_withoutConnecting) {
|
|
1503
|
-
internalRoom.connect();
|
|
1504
|
-
}
|
|
1505
|
-
|
|
1506
|
-
return internalRoom.room;
|
|
1507
|
-
}
|
|
1508
|
-
|
|
1509
|
-
function leave(roomId) {
|
|
1510
|
-
var room = rooms.get(roomId);
|
|
1511
|
-
|
|
1512
|
-
if (room) {
|
|
1513
|
-
room.disconnect();
|
|
1514
|
-
rooms.delete(roomId);
|
|
1515
|
-
}
|
|
1516
|
-
}
|
|
1517
|
-
|
|
1518
|
-
if (typeof window !== "undefined") {
|
|
1519
|
-
window.addEventListener("online", function () {
|
|
1520
|
-
for (var _iterator = LiveObject._createForOfIteratorHelperLoose(rooms), _step; !(_step = _iterator()).done;) {
|
|
1521
|
-
var _step$value = _step.value,
|
|
1522
|
-
room = _step$value[1];
|
|
1523
|
-
room.onNavigatorOnline();
|
|
1524
|
-
}
|
|
1525
|
-
});
|
|
1526
|
-
}
|
|
1527
|
-
|
|
1528
|
-
if (typeof document !== "undefined") {
|
|
1529
|
-
document.addEventListener("visibilitychange", function () {
|
|
1530
|
-
for (var _iterator2 = LiveObject._createForOfIteratorHelperLoose(rooms), _step2; !(_step2 = _iterator2()).done;) {
|
|
1531
|
-
var _step2$value = _step2.value,
|
|
1532
|
-
room = _step2$value[1];
|
|
1533
|
-
room.onVisibilityChange(document.visibilityState);
|
|
1534
|
-
}
|
|
1535
|
-
});
|
|
1536
|
-
}
|
|
1537
|
-
|
|
1538
|
-
return {
|
|
1539
|
-
getRoom: getRoom,
|
|
1540
|
-
enter: enter,
|
|
1541
|
-
leave: leave
|
|
1542
|
-
};
|
|
1543
|
-
}
|
|
1544
|
-
|
|
1545
|
-
function getThrottleDelayFromOptions(options) {
|
|
1546
|
-
if (options.throttle === undefined) {
|
|
1547
|
-
return 100;
|
|
1548
|
-
}
|
|
1549
|
-
|
|
1550
|
-
if (typeof options.throttle !== "number" || options.throttle < 80 || options.throttle > 1000) {
|
|
1551
|
-
throw new Error("throttle should be a number between 80 and 1000.");
|
|
1552
|
-
}
|
|
1553
|
-
|
|
1554
|
-
return options.throttle;
|
|
1555
|
-
}
|
|
1556
|
-
|
|
1557
795
|
function prepareAuthentication(clientOptions) {
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
callback: clientOptions.authEndpoint
|
|
1573
|
-
};
|
|
1574
|
-
}
|
|
1575
|
-
|
|
1576
|
-
throw new Error("Invalid Liveblocks client options. For more information: https://liveblocks.io/docs/api-reference/liveblocks-client#createClient");
|
|
796
|
+
if ("string" == typeof clientOptions.publicApiKey) return {
|
|
797
|
+
type: "public",
|
|
798
|
+
publicApiKey: clientOptions.publicApiKey,
|
|
799
|
+
url: clientOptions.publicAuthorizeEndpoint || "https://liveblocks.io/api/public/authorize"
|
|
800
|
+
};
|
|
801
|
+
if ("string" == typeof clientOptions.authEndpoint) return {
|
|
802
|
+
type: "private",
|
|
803
|
+
url: clientOptions.authEndpoint
|
|
804
|
+
};
|
|
805
|
+
if ("function" == typeof clientOptions.authEndpoint) return {
|
|
806
|
+
type: "custom",
|
|
807
|
+
callback: clientOptions.authEndpoint
|
|
808
|
+
};
|
|
809
|
+
throw new Error("Invalid Liveblocks client options. For more information: https://liveblocks.io/docs/api-reference/liveblocks-client#createClient");
|
|
1577
810
|
}
|
|
1578
811
|
|
|
1579
|
-
exports.LiveList = LiveObject.LiveList
|
|
1580
|
-
exports.
|
|
1581
|
-
|
|
1582
|
-
|
|
812
|
+
exports.LiveList = LiveObject.LiveList, exports.LiveMap = LiveObject.LiveMap, exports.LiveObject = LiveObject.LiveObject,
|
|
813
|
+
exports.createClient = function(options) {
|
|
814
|
+
var clientOptions = options, throttleDelay = function(options) {
|
|
815
|
+
if (void 0 === options.throttle) return 100;
|
|
816
|
+
if ("number" != typeof options.throttle || options.throttle < 80 || options.throttle > 1e3) throw new Error("throttle should be a number between 80 and 1000.");
|
|
817
|
+
return options.throttle;
|
|
818
|
+
}(options), rooms = new Map;
|
|
819
|
+
return "undefined" != typeof window && window.addEventListener("online", (function() {
|
|
820
|
+
for (var _step, _iterator = LiveObject._createForOfIteratorHelperLoose(rooms); !(_step = _iterator()).done; ) {
|
|
821
|
+
_step.value[1].onNavigatorOnline();
|
|
822
|
+
}
|
|
823
|
+
})), "undefined" != typeof document && document.addEventListener("visibilitychange", (function() {
|
|
824
|
+
for (var _step2, _iterator2 = LiveObject._createForOfIteratorHelperLoose(rooms); !(_step2 = _iterator2()).done; ) {
|
|
825
|
+
_step2.value[1].onVisibilityChange(document.visibilityState);
|
|
826
|
+
}
|
|
827
|
+
})), {
|
|
828
|
+
getRoom: function(roomId) {
|
|
829
|
+
var internalRoom = rooms.get(roomId);
|
|
830
|
+
return internalRoom ? internalRoom.room : null;
|
|
831
|
+
},
|
|
832
|
+
enter: function(roomId, options) {
|
|
833
|
+
void 0 === options && (options = {});
|
|
834
|
+
var internalRoom = rooms.get(roomId);
|
|
835
|
+
return internalRoom || (LiveObject.deprecateIf(options.defaultPresence, "Argument `defaultPresence` will be removed in @liveblocks/client 0.18. Please use `initialPresence` instead. For more info, see https://bit.ly/3Niy5aP", "defaultPresence"),
|
|
836
|
+
LiveObject.deprecateIf(options.defaultStorageRoot, "Argument `defaultStorageRoot` will be removed in @liveblocks/client 0.18. Please use `initialStorage` instead. For more info, see https://bit.ly/3Niy5aP", "defaultStorageRoot"),
|
|
837
|
+
internalRoom = createRoom({
|
|
838
|
+
initialPresence: options.initialPresence,
|
|
839
|
+
initialStorage: options.initialStorage,
|
|
840
|
+
defaultPresence: options.defaultPresence,
|
|
841
|
+
defaultStorageRoot: options.defaultStorageRoot
|
|
842
|
+
}, {
|
|
843
|
+
roomId: roomId,
|
|
844
|
+
throttleDelay: throttleDelay,
|
|
845
|
+
WebSocketPolyfill: clientOptions.WebSocketPolyfill,
|
|
846
|
+
fetchPolyfill: clientOptions.fetchPolyfill,
|
|
847
|
+
liveblocksServer: clientOptions.liveblocksServer || "wss://liveblocks.net/v5",
|
|
848
|
+
authentication: prepareAuthentication(clientOptions)
|
|
849
|
+
}), rooms.set(roomId, internalRoom), options.DO_NOT_USE_withoutConnecting || internalRoom.connect()),
|
|
850
|
+
internalRoom.room;
|
|
851
|
+
},
|
|
852
|
+
leave: function(roomId) {
|
|
853
|
+
var room = rooms.get(roomId);
|
|
854
|
+
room && (room.disconnect(), rooms.delete(roomId));
|
|
855
|
+
}
|
|
856
|
+
};
|
|
857
|
+
};
|