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