matrix-js-sdk 37.2.0 → 37.3.0-rc.0
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/git-revision.txt +1 -1
- package/lib/client.d.ts +8 -2
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +11 -3
- package/lib/client.js.map +1 -1
- package/lib/common-crypto/CryptoBackend.d.ts +8 -0
- package/lib/common-crypto/CryptoBackend.d.ts.map +1 -1
- package/lib/common-crypto/CryptoBackend.js.map +1 -1
- package/lib/http-api/errors.d.ts +8 -0
- package/lib/http-api/errors.d.ts.map +1 -1
- package/lib/http-api/errors.js +14 -0
- package/lib/http-api/errors.js.map +1 -1
- package/lib/http-api/fetch.d.ts.map +1 -1
- package/lib/http-api/fetch.js +3 -3
- package/lib/http-api/fetch.js.map +1 -1
- package/lib/matrixrtc/LegacyMembershipManager.d.ts +9 -1
- package/lib/matrixrtc/LegacyMembershipManager.d.ts.map +1 -1
- package/lib/matrixrtc/LegacyMembershipManager.js +20 -0
- package/lib/matrixrtc/LegacyMembershipManager.js.map +1 -1
- package/lib/matrixrtc/MatrixRTCSession.d.ts.map +1 -1
- package/lib/matrixrtc/MatrixRTCSession.js.map +1 -1
- package/lib/matrixrtc/NewMembershipManager.d.ts +7 -58
- package/lib/matrixrtc/NewMembershipManager.d.ts.map +1 -1
- package/lib/matrixrtc/NewMembershipManager.js +130 -137
- package/lib/matrixrtc/NewMembershipManager.js.map +1 -1
- package/lib/matrixrtc/NewMembershipManagerActionScheduler.js +3 -3
- package/lib/matrixrtc/NewMembershipManagerActionScheduler.js.map +1 -1
- package/lib/matrixrtc/index.d.ts +1 -0
- package/lib/matrixrtc/index.d.ts.map +1 -1
- package/lib/matrixrtc/index.js +1 -0
- package/lib/matrixrtc/index.js.map +1 -1
- package/lib/matrixrtc/types.d.ts +77 -1
- package/lib/matrixrtc/types.d.ts.map +1 -1
- package/lib/matrixrtc/types.js +40 -1
- package/lib/matrixrtc/types.js.map +1 -1
- package/lib/models/room-summary.d.ts +30 -0
- package/lib/models/room-summary.d.ts.map +1 -1
- package/lib/models/room-summary.js +11 -0
- package/lib/models/room-summary.js.map +1 -1
- package/lib/models/room.d.ts +37 -1
- package/lib/models/room.d.ts.map +1 -1
- package/lib/models/room.js +133 -28
- package/lib/models/room.js.map +1 -1
- package/lib/oidc/tokenRefresher.d.ts.map +1 -1
- package/lib/oidc/tokenRefresher.js +8 -1
- package/lib/oidc/tokenRefresher.js.map +1 -1
- package/lib/pushprocessor.d.ts +10 -1
- package/lib/pushprocessor.d.ts.map +1 -1
- package/lib/pushprocessor.js +24 -9
- package/lib/pushprocessor.js.map +1 -1
- package/lib/rust-crypto/OutgoingRequestProcessor.d.ts.map +1 -1
- package/lib/rust-crypto/OutgoingRequestProcessor.js +6 -1
- package/lib/rust-crypto/OutgoingRequestProcessor.js.map +1 -1
- package/lib/rust-crypto/rust-crypto.d.ts +4 -1
- package/lib/rust-crypto/rust-crypto.d.ts.map +1 -1
- package/lib/rust-crypto/rust-crypto.js +55 -46
- package/lib/rust-crypto/rust-crypto.js.map +1 -1
- package/lib/sliding-sync-sdk.d.ts.map +1 -1
- package/lib/sliding-sync-sdk.js +86 -75
- package/lib/sliding-sync-sdk.js.map +1 -1
- package/lib/sliding-sync.d.ts +23 -60
- package/lib/sliding-sync.d.ts.map +1 -1
- package/lib/sliding-sync.js +62 -321
- package/lib/sliding-sync.js.map +1 -1
- package/package.json +6 -6
- package/src/client.ts +12 -5
- package/src/common-crypto/CryptoBackend.ts +9 -0
- package/src/http-api/errors.ts +14 -0
- package/src/http-api/fetch.ts +3 -4
- package/src/matrixrtc/LegacyMembershipManager.ts +27 -1
- package/src/matrixrtc/MatrixRTCSession.ts +2 -1
- package/src/matrixrtc/NewMembershipManager.ts +120 -165
- package/src/matrixrtc/NewMembershipManagerActionScheduler.ts +3 -3
- package/src/matrixrtc/index.ts +1 -0
- package/src/matrixrtc/types.ts +84 -1
- package/src/models/room-summary.ts +31 -0
- package/src/models/room.ts +133 -23
- package/src/oidc/tokenRefresher.ts +8 -2
- package/src/pushprocessor.ts +25 -16
- package/src/rust-crypto/OutgoingRequestProcessor.ts +6 -0
- package/src/rust-crypto/rust-crypto.ts +7 -1
- package/src/sliding-sync-sdk.ts +28 -28
- package/src/sliding-sync.ts +38 -329
package/lib/sliding-sync.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
2
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
3
|
-
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
4
|
-
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
5
3
|
/*
|
|
6
|
-
Copyright 2022 The Matrix.org Foundation C.I.C.
|
|
4
|
+
Copyright 2022-2024 The Matrix.org Foundation C.I.C.
|
|
7
5
|
|
|
8
6
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
9
7
|
you may not use this file except in compliance with the License.
|
|
@@ -20,7 +18,7 @@ limitations under the License.
|
|
|
20
18
|
|
|
21
19
|
import { logger } from "./logger.js";
|
|
22
20
|
import { TypedEventEmitter } from "./models/typed-event-emitter.js";
|
|
23
|
-
import { sleep
|
|
21
|
+
import { sleep } from "./utils.js";
|
|
24
22
|
// /sync requests allow you to set a timeout= but the request may continue
|
|
25
23
|
// beyond that and wedge forever, so we need to track how long we are willing
|
|
26
24
|
// to keep open the connection. This constant is *ADDED* to the timeout= value
|
|
@@ -46,6 +44,13 @@ export var MSC3575_STATE_KEY_LAZY = "$LAZY";
|
|
|
46
44
|
* A complete Sliding Sync request.
|
|
47
45
|
*/
|
|
48
46
|
|
|
47
|
+
/**
|
|
48
|
+
* New format of hero introduced in MSC4186 with display name and avatar URL
|
|
49
|
+
* in addition to just user_id (as it is on the wire, with underscores)
|
|
50
|
+
* as opposed to Hero in room-summary.ts which has fields in camelCase
|
|
51
|
+
* (and also a flag to note what format the hero came from).
|
|
52
|
+
*/
|
|
53
|
+
|
|
49
54
|
/**
|
|
50
55
|
* A complete Sliding Sync response
|
|
51
56
|
*/
|
|
@@ -69,7 +74,6 @@ class SlidingList {
|
|
|
69
74
|
_defineProperty(this, "list", void 0);
|
|
70
75
|
_defineProperty(this, "isModified", void 0);
|
|
71
76
|
// returned data
|
|
72
|
-
_defineProperty(this, "roomIndexToRoomId", {});
|
|
73
77
|
_defineProperty(this, "joinedCount", 0);
|
|
74
78
|
this.replaceList(list);
|
|
75
79
|
}
|
|
@@ -105,9 +109,6 @@ class SlidingList {
|
|
|
105
109
|
// reset values as the join count may be very different (if filters changed) including the rooms
|
|
106
110
|
// (e.g. sort orders or sliding window ranges changed)
|
|
107
111
|
|
|
108
|
-
// the constantly changing sliding window ranges. Not an array for performance reasons
|
|
109
|
-
// E.g. tracking ranges 0-99, 500-599, we don't want to have a 600 element array
|
|
110
|
-
this.roomIndexToRoomId = {};
|
|
111
112
|
// the total number of joined rooms according to the server, always >= len(roomIndexToRoomId)
|
|
112
113
|
this.joinedCount = 0;
|
|
113
114
|
}
|
|
@@ -127,26 +128,6 @@ class SlidingList {
|
|
|
127
128
|
}
|
|
128
129
|
return list;
|
|
129
130
|
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Check if a given index is within the list range. This is required even though the /sync API
|
|
133
|
-
* provides explicit updates with index positions because of the following situation:
|
|
134
|
-
* 0 1 2 3 4 5 6 7 8 indexes
|
|
135
|
-
* a b c d e f COMMANDS: SYNC 0 2 a b c; SYNC 6 8 d e f;
|
|
136
|
-
* a b c d _ f COMMAND: DELETE 7;
|
|
137
|
-
* e a b c d f COMMAND: INSERT 0 e;
|
|
138
|
-
* c=3 is wrong as we are not tracking it, ergo we need to see if `i` is in range else drop it
|
|
139
|
-
* @param i - The index to check
|
|
140
|
-
* @returns True if the index is within a sliding window
|
|
141
|
-
*/
|
|
142
|
-
isIndexInRange(i) {
|
|
143
|
-
for (var r of this.list.ranges) {
|
|
144
|
-
if (r[0] <= i && i <= r[1]) {
|
|
145
|
-
return true;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
131
|
}
|
|
151
132
|
|
|
152
133
|
/**
|
|
@@ -167,17 +148,14 @@ export var ExtensionState = /*#__PURE__*/function (ExtensionState) {
|
|
|
167
148
|
* of information when processing sync responses.
|
|
168
149
|
* - RoomData: concerns rooms, useful for SlidingSyncSdk to update its knowledge of rooms.
|
|
169
150
|
* - Lifecycle: concerns callbacks at various well-defined points in the sync process.
|
|
170
|
-
* - List: concerns lists, useful for UI layers to re-render room lists.
|
|
171
151
|
* Specifically, the order of event invocation is:
|
|
172
152
|
* - Lifecycle (state=RequestFinished)
|
|
173
153
|
* - RoomData (N times)
|
|
174
154
|
* - Lifecycle (state=Complete)
|
|
175
|
-
* - List (at most once per list)
|
|
176
155
|
*/
|
|
177
156
|
export var SlidingSyncEvent = /*#__PURE__*/function (SlidingSyncEvent) {
|
|
178
157
|
SlidingSyncEvent["RoomData"] = "SlidingSync.RoomData";
|
|
179
158
|
SlidingSyncEvent["Lifecycle"] = "SlidingSync.Lifecycle";
|
|
180
|
-
SlidingSyncEvent["List"] = "SlidingSync.List";
|
|
181
159
|
return SlidingSyncEvent;
|
|
182
160
|
}({});
|
|
183
161
|
/**
|
|
@@ -206,11 +184,6 @@ export class SlidingSync extends TypedEventEmitter {
|
|
|
206
184
|
_defineProperty(this, "terminated", false);
|
|
207
185
|
// flag set when resend() is called because we cannot rely on detecting AbortError in JS SDK :(
|
|
208
186
|
_defineProperty(this, "needsResend", false);
|
|
209
|
-
// the txn_id to send with the next request.
|
|
210
|
-
_defineProperty(this, "txnId", null);
|
|
211
|
-
// a list (in chronological order of when they were sent) of objects containing the txn ID and
|
|
212
|
-
// a defer to resolve/reject depending on whether they were successfully sent or not.
|
|
213
|
-
_defineProperty(this, "txnIdDefers", []);
|
|
214
187
|
// map of extension name to req/resp handler
|
|
215
188
|
_defineProperty(this, "extensions", {});
|
|
216
189
|
_defineProperty(this, "desiredRoomSubscriptions", new Set());
|
|
@@ -272,8 +245,7 @@ export class SlidingSync extends TypedEventEmitter {
|
|
|
272
245
|
return null;
|
|
273
246
|
}
|
|
274
247
|
return {
|
|
275
|
-
joinedCount: data.joinedCount
|
|
276
|
-
roomIndexToRoomId: Object.assign({}, data.roomIndexToRoomId)
|
|
248
|
+
joinedCount: data.joinedCount
|
|
277
249
|
};
|
|
278
250
|
}
|
|
279
251
|
|
|
@@ -304,10 +276,10 @@ export class SlidingSync extends TypedEventEmitter {
|
|
|
304
276
|
setListRanges(key, ranges) {
|
|
305
277
|
var list = this.lists.get(key);
|
|
306
278
|
if (!list) {
|
|
307
|
-
|
|
279
|
+
throw new Error("no list with key " + key);
|
|
308
280
|
}
|
|
309
281
|
list.updateListRange(ranges);
|
|
310
|
-
|
|
282
|
+
this.resend();
|
|
311
283
|
}
|
|
312
284
|
|
|
313
285
|
/**
|
|
@@ -328,7 +300,7 @@ export class SlidingSync extends TypedEventEmitter {
|
|
|
328
300
|
this.lists.set(key, new SlidingList(list));
|
|
329
301
|
}
|
|
330
302
|
this.listModifiedCount += 1;
|
|
331
|
-
|
|
303
|
+
this.resend();
|
|
332
304
|
}
|
|
333
305
|
|
|
334
306
|
/**
|
|
@@ -344,27 +316,21 @@ export class SlidingSync extends TypedEventEmitter {
|
|
|
344
316
|
* /sync request to resend new subscriptions. If the /sync stream has not started, this will
|
|
345
317
|
* prepare the room subscriptions for when start() is called.
|
|
346
318
|
* @param s - The new desired room subscriptions.
|
|
347
|
-
* @returns A promise which resolves to the transaction ID when it has been received down sync
|
|
348
|
-
* (or rejects with the transaction ID if the action was not applied e.g the request was cancelled
|
|
349
|
-
* immediately after sending, in which case the action will be applied in the subsequent request)
|
|
350
319
|
*/
|
|
351
320
|
modifyRoomSubscriptions(s) {
|
|
352
321
|
this.desiredRoomSubscriptions = s;
|
|
353
|
-
|
|
322
|
+
this.resend();
|
|
354
323
|
}
|
|
355
324
|
|
|
356
325
|
/**
|
|
357
326
|
* Modify which events to retrieve for room subscriptions. Invalidates all room subscriptions
|
|
358
327
|
* such that they will be sent up afresh.
|
|
359
328
|
* @param rs - The new room subscription fields to fetch.
|
|
360
|
-
* @returns A promise which resolves to the transaction ID when it has been received down sync
|
|
361
|
-
* (or rejects with the transaction ID if the action was not applied e.g the request was cancelled
|
|
362
|
-
* immediately after sending, in which case the action will be applied in the subsequent request)
|
|
363
329
|
*/
|
|
364
330
|
modifyRoomSubscriptionInfo(rs) {
|
|
365
331
|
this.roomSubscriptionInfo = rs;
|
|
366
332
|
this.confirmedRoomSubscriptions = new Set();
|
|
367
|
-
|
|
333
|
+
this.resend();
|
|
368
334
|
}
|
|
369
335
|
|
|
370
336
|
/**
|
|
@@ -378,19 +344,22 @@ export class SlidingSync extends TypedEventEmitter {
|
|
|
378
344
|
this.extensions[ext.name()] = ext;
|
|
379
345
|
}
|
|
380
346
|
getExtensionRequest(isInitial) {
|
|
381
|
-
var
|
|
382
|
-
|
|
383
|
-
ext
|
|
384
|
-
|
|
385
|
-
|
|
347
|
+
var _this = this;
|
|
348
|
+
return _asyncToGenerator(function* () {
|
|
349
|
+
var ext = {};
|
|
350
|
+
for (var extName in _this.extensions) {
|
|
351
|
+
ext[extName] = yield _this.extensions[extName].onRequest(isInitial);
|
|
352
|
+
}
|
|
353
|
+
return ext;
|
|
354
|
+
})();
|
|
386
355
|
}
|
|
387
356
|
onPreExtensionsResponse(ext) {
|
|
388
|
-
var
|
|
357
|
+
var _this2 = this;
|
|
389
358
|
return _asyncToGenerator(function* () {
|
|
390
359
|
yield Promise.all(Object.keys(ext).map(/*#__PURE__*/function () {
|
|
391
360
|
var _ref = _asyncToGenerator(function* (extName) {
|
|
392
|
-
if (
|
|
393
|
-
yield
|
|
361
|
+
if (_this2.extensions[extName].when() == ExtensionState.PreProcess) {
|
|
362
|
+
yield _this2.extensions[extName].onResponse(ext[extName]);
|
|
394
363
|
}
|
|
395
364
|
});
|
|
396
365
|
return function (_x) {
|
|
@@ -400,12 +369,12 @@ export class SlidingSync extends TypedEventEmitter {
|
|
|
400
369
|
})();
|
|
401
370
|
}
|
|
402
371
|
onPostExtensionsResponse(ext) {
|
|
403
|
-
var
|
|
372
|
+
var _this3 = this;
|
|
404
373
|
return _asyncToGenerator(function* () {
|
|
405
374
|
yield Promise.all(Object.keys(ext).map(/*#__PURE__*/function () {
|
|
406
375
|
var _ref2 = _asyncToGenerator(function* (extName) {
|
|
407
|
-
if (
|
|
408
|
-
yield
|
|
376
|
+
if (_this3.extensions[extName].when() == ExtensionState.PostProcess) {
|
|
377
|
+
yield _this3.extensions[extName].onResponse(ext[extName]);
|
|
409
378
|
}
|
|
410
379
|
});
|
|
411
380
|
return function (_x2) {
|
|
@@ -421,7 +390,7 @@ export class SlidingSync extends TypedEventEmitter {
|
|
|
421
390
|
* @param roomData - The raw sliding sync response JSON.
|
|
422
391
|
*/
|
|
423
392
|
invokeRoomDataListeners(roomId, roomData) {
|
|
424
|
-
var
|
|
393
|
+
var _this4 = this;
|
|
425
394
|
return _asyncToGenerator(function* () {
|
|
426
395
|
if (!roomData.required_state) {
|
|
427
396
|
roomData.required_state = [];
|
|
@@ -429,7 +398,7 @@ export class SlidingSync extends TypedEventEmitter {
|
|
|
429
398
|
if (!roomData.timeline) {
|
|
430
399
|
roomData.timeline = [];
|
|
431
400
|
}
|
|
432
|
-
yield
|
|
401
|
+
yield _this4.emitPromised(SlidingSyncEvent.RoomData, roomId, roomData);
|
|
433
402
|
})();
|
|
434
403
|
}
|
|
435
404
|
|
|
@@ -442,202 +411,15 @@ export class SlidingSync extends TypedEventEmitter {
|
|
|
442
411
|
invokeLifecycleListeners(state, resp, err) {
|
|
443
412
|
this.emit(SlidingSyncEvent.Lifecycle, state, resp, err);
|
|
444
413
|
}
|
|
445
|
-
shiftRight(listKey, hi, low) {
|
|
446
|
-
var list = this.lists.get(listKey);
|
|
447
|
-
if (!list) {
|
|
448
|
-
return;
|
|
449
|
-
}
|
|
450
|
-
// l h
|
|
451
|
-
// 0,1,2,3,4 <- before
|
|
452
|
-
// 0,1,2,2,3 <- after, hi is deleted and low is duplicated
|
|
453
|
-
for (var i = hi; i > low; i--) {
|
|
454
|
-
if (list.isIndexInRange(i)) {
|
|
455
|
-
list.roomIndexToRoomId[i] = list.roomIndexToRoomId[i - 1];
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
shiftLeft(listKey, hi, low) {
|
|
460
|
-
var list = this.lists.get(listKey);
|
|
461
|
-
if (!list) {
|
|
462
|
-
return;
|
|
463
|
-
}
|
|
464
|
-
// l h
|
|
465
|
-
// 0,1,2,3,4 <- before
|
|
466
|
-
// 0,1,3,4,4 <- after, low is deleted and hi is duplicated
|
|
467
|
-
for (var i = low; i < hi; i++) {
|
|
468
|
-
if (list.isIndexInRange(i)) {
|
|
469
|
-
list.roomIndexToRoomId[i] = list.roomIndexToRoomId[i + 1];
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
removeEntry(listKey, index) {
|
|
474
|
-
var list = this.lists.get(listKey);
|
|
475
|
-
if (!list) {
|
|
476
|
-
return;
|
|
477
|
-
}
|
|
478
|
-
// work out the max index
|
|
479
|
-
var max = -1;
|
|
480
|
-
for (var n in list.roomIndexToRoomId) {
|
|
481
|
-
if (Number(n) > max) {
|
|
482
|
-
max = Number(n);
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
if (max < 0 || index > max) {
|
|
486
|
-
return;
|
|
487
|
-
}
|
|
488
|
-
// Everything higher than the gap needs to be shifted left.
|
|
489
|
-
this.shiftLeft(listKey, max, index);
|
|
490
|
-
delete list.roomIndexToRoomId[max];
|
|
491
|
-
}
|
|
492
|
-
addEntry(listKey, index) {
|
|
493
|
-
var list = this.lists.get(listKey);
|
|
494
|
-
if (!list) {
|
|
495
|
-
return;
|
|
496
|
-
}
|
|
497
|
-
// work out the max index
|
|
498
|
-
var max = -1;
|
|
499
|
-
for (var n in list.roomIndexToRoomId) {
|
|
500
|
-
if (Number(n) > max) {
|
|
501
|
-
max = Number(n);
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
if (max < 0 || index > max) {
|
|
505
|
-
return;
|
|
506
|
-
}
|
|
507
|
-
// Everything higher than the gap needs to be shifted right, +1 so we don't delete the highest element
|
|
508
|
-
this.shiftRight(listKey, max + 1, index);
|
|
509
|
-
}
|
|
510
|
-
processListOps(list, listKey) {
|
|
511
|
-
var gapIndex = -1;
|
|
512
|
-
var listData = this.lists.get(listKey);
|
|
513
|
-
if (!listData) {
|
|
514
|
-
return;
|
|
515
|
-
}
|
|
516
|
-
list.ops.forEach(op => {
|
|
517
|
-
if (!listData) {
|
|
518
|
-
return;
|
|
519
|
-
}
|
|
520
|
-
switch (op.op) {
|
|
521
|
-
case "DELETE":
|
|
522
|
-
{
|
|
523
|
-
logger.debug("DELETE", listKey, op.index, ";");
|
|
524
|
-
delete listData.roomIndexToRoomId[op.index];
|
|
525
|
-
if (gapIndex !== -1) {
|
|
526
|
-
// we already have a DELETE operation to process, so process it.
|
|
527
|
-
this.removeEntry(listKey, gapIndex);
|
|
528
|
-
}
|
|
529
|
-
gapIndex = op.index;
|
|
530
|
-
break;
|
|
531
|
-
}
|
|
532
|
-
case "INSERT":
|
|
533
|
-
{
|
|
534
|
-
logger.debug("INSERT", listKey, op.index, op.room_id, ";");
|
|
535
|
-
if (listData.roomIndexToRoomId[op.index]) {
|
|
536
|
-
// something is in this space, shift items out of the way
|
|
537
|
-
if (gapIndex < 0) {
|
|
538
|
-
// we haven't been told where to shift from, so make way for a new room entry.
|
|
539
|
-
this.addEntry(listKey, op.index);
|
|
540
|
-
} else if (gapIndex > op.index) {
|
|
541
|
-
// the gap is further down the list, shift every element to the right
|
|
542
|
-
// starting at the gap so we can just shift each element in turn:
|
|
543
|
-
// [A,B,C,_] gapIndex=3, op.index=0
|
|
544
|
-
// [A,B,C,C] i=3
|
|
545
|
-
// [A,B,B,C] i=2
|
|
546
|
-
// [A,A,B,C] i=1
|
|
547
|
-
// Terminate. We'll assign into op.index next.
|
|
548
|
-
this.shiftRight(listKey, gapIndex, op.index);
|
|
549
|
-
} else if (gapIndex < op.index) {
|
|
550
|
-
// the gap is further up the list, shift every element to the left
|
|
551
|
-
// starting at the gap so we can just shift each element in turn
|
|
552
|
-
this.shiftLeft(listKey, op.index, gapIndex);
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
// forget the gap, we don't need it anymore. This is outside the check for
|
|
556
|
-
// a room being present in this index position because INSERTs always universally
|
|
557
|
-
// forget the gap, not conditionally based on the presence of a room in the INSERT
|
|
558
|
-
// position. Without this, DELETE 0; INSERT 0; would do the wrong thing.
|
|
559
|
-
gapIndex = -1;
|
|
560
|
-
listData.roomIndexToRoomId[op.index] = op.room_id;
|
|
561
|
-
break;
|
|
562
|
-
}
|
|
563
|
-
case "INVALIDATE":
|
|
564
|
-
{
|
|
565
|
-
var startIndex = op.range[0];
|
|
566
|
-
for (var i = startIndex; i <= op.range[1]; i++) {
|
|
567
|
-
delete listData.roomIndexToRoomId[i];
|
|
568
|
-
}
|
|
569
|
-
logger.debug("INVALIDATE", listKey, op.range[0], op.range[1], ";");
|
|
570
|
-
break;
|
|
571
|
-
}
|
|
572
|
-
case "SYNC":
|
|
573
|
-
{
|
|
574
|
-
var _startIndex = op.range[0];
|
|
575
|
-
for (var _i = _startIndex; _i <= op.range[1]; _i++) {
|
|
576
|
-
var roomId = op.room_ids[_i - _startIndex];
|
|
577
|
-
if (!roomId) {
|
|
578
|
-
break; // we are at the end of list
|
|
579
|
-
}
|
|
580
|
-
listData.roomIndexToRoomId[_i] = roomId;
|
|
581
|
-
}
|
|
582
|
-
logger.debug("SYNC", listKey, op.range[0], op.range[1], (op.room_ids || []).join(" "), ";");
|
|
583
|
-
break;
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
});
|
|
587
|
-
if (gapIndex !== -1) {
|
|
588
|
-
// we already have a DELETE operation to process, so process it
|
|
589
|
-
// Everything higher than the gap needs to be shifted left.
|
|
590
|
-
this.removeEntry(listKey, gapIndex);
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
414
|
|
|
594
415
|
/**
|
|
595
|
-
* Resend a Sliding Sync request. Used when something has changed in the request.
|
|
596
|
-
* the transaction ID of this request on success. Rejects with the transaction ID of this request
|
|
597
|
-
* on failure.
|
|
416
|
+
* Resend a Sliding Sync request. Used when something has changed in the request.
|
|
598
417
|
*/
|
|
599
418
|
resend() {
|
|
600
419
|
var _this$abortController;
|
|
601
|
-
if (this.needsResend && this.txnIdDefers.length > 0) {
|
|
602
|
-
// we already have a resend queued, so just return the same promise
|
|
603
|
-
return this.txnIdDefers[this.txnIdDefers.length - 1].promise;
|
|
604
|
-
}
|
|
605
420
|
this.needsResend = true;
|
|
606
|
-
this.txnId = this.client.makeTxnId();
|
|
607
|
-
var d = defer();
|
|
608
|
-
this.txnIdDefers.push(_objectSpread(_objectSpread({}, d), {}, {
|
|
609
|
-
txnId: this.txnId
|
|
610
|
-
}));
|
|
611
421
|
(_this$abortController = this.abortController) === null || _this$abortController === void 0 || _this$abortController.abort();
|
|
612
422
|
this.abortController = new AbortController();
|
|
613
|
-
return d.promise;
|
|
614
|
-
}
|
|
615
|
-
resolveTransactionDefers(txnId) {
|
|
616
|
-
if (!txnId) {
|
|
617
|
-
return;
|
|
618
|
-
}
|
|
619
|
-
// find the matching index
|
|
620
|
-
var txnIndex = -1;
|
|
621
|
-
for (var i = 0; i < this.txnIdDefers.length; i++) {
|
|
622
|
-
if (this.txnIdDefers[i].txnId === txnId) {
|
|
623
|
-
txnIndex = i;
|
|
624
|
-
break;
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
if (txnIndex === -1) {
|
|
628
|
-
// this shouldn't happen; we shouldn't be seeing txn_ids for things we don't know about,
|
|
629
|
-
// whine about it.
|
|
630
|
-
logger.warn("resolveTransactionDefers: seen ".concat(txnId, " but it isn't a pending txn, ignoring."));
|
|
631
|
-
return;
|
|
632
|
-
}
|
|
633
|
-
// This list is sorted in time, so if the input txnId ACKs in the middle of this array,
|
|
634
|
-
// then everything before it that hasn't been ACKed yet never will and we should reject them.
|
|
635
|
-
for (var _i2 = 0; _i2 < txnIndex; _i2++) {
|
|
636
|
-
this.txnIdDefers[_i2].reject(this.txnIdDefers[_i2].txnId);
|
|
637
|
-
}
|
|
638
|
-
this.txnIdDefers[txnIndex].resolve(txnId);
|
|
639
|
-
// clear out settled promises, including the one we resolved.
|
|
640
|
-
this.txnIdDefers = this.txnIdDefers.slice(txnIndex + 1);
|
|
641
423
|
}
|
|
642
424
|
|
|
643
425
|
/**
|
|
@@ -649,7 +431,6 @@ export class SlidingSync extends TypedEventEmitter {
|
|
|
649
431
|
(_this$abortController2 = this.abortController) === null || _this$abortController2 === void 0 || _this$abortController2.abort();
|
|
650
432
|
// remove all listeners so things can be GC'd
|
|
651
433
|
this.removeAllListeners(SlidingSyncEvent.Lifecycle);
|
|
652
|
-
this.removeAllListeners(SlidingSyncEvent.List);
|
|
653
434
|
this.removeAllListeners(SlidingSyncEvent.RoomData);
|
|
654
435
|
}
|
|
655
436
|
|
|
@@ -657,90 +438,69 @@ export class SlidingSync extends TypedEventEmitter {
|
|
|
657
438
|
* Re-setup this connection e.g in the event of an expired session.
|
|
658
439
|
*/
|
|
659
440
|
resetup() {
|
|
660
|
-
var _this$abortController3;
|
|
661
441
|
logger.warn("SlidingSync: resetting connection info");
|
|
662
|
-
// any pending txn ID defers will be forgotten already by the server, so clear them out
|
|
663
|
-
this.txnIdDefers.forEach(d => {
|
|
664
|
-
d.reject(d.txnId);
|
|
665
|
-
});
|
|
666
|
-
this.txnIdDefers = [];
|
|
667
442
|
// resend sticky params and de-confirm all subscriptions
|
|
668
443
|
this.lists.forEach(l => {
|
|
669
444
|
l.setModified(true);
|
|
670
445
|
});
|
|
671
446
|
this.confirmedRoomSubscriptions = new Set(); // leave desired ones alone though!
|
|
672
447
|
// reset the connection as we might be wedged
|
|
673
|
-
this.
|
|
674
|
-
(_this$abortController3 = this.abortController) === null || _this$abortController3 === void 0 || _this$abortController3.abort();
|
|
675
|
-
this.abortController = new AbortController();
|
|
448
|
+
this.resend();
|
|
676
449
|
}
|
|
677
450
|
|
|
678
451
|
/**
|
|
679
452
|
* Start syncing with the server. Blocks until stopped.
|
|
680
453
|
*/
|
|
681
454
|
start() {
|
|
682
|
-
var
|
|
455
|
+
var _this5 = this;
|
|
683
456
|
return _asyncToGenerator(function* () {
|
|
684
|
-
|
|
457
|
+
_this5.abortController = new AbortController();
|
|
685
458
|
var currentPos;
|
|
686
459
|
var _loop = function* _loop() {
|
|
687
|
-
|
|
688
|
-
var doNotUpdateList = false;
|
|
460
|
+
_this5.needsResend = false;
|
|
689
461
|
var resp;
|
|
690
462
|
try {
|
|
691
463
|
var _resp$lists, _resp$rooms, _resp$extensions;
|
|
692
|
-
var listModifiedCount = _this4.listModifiedCount;
|
|
693
464
|
var reqLists = {};
|
|
694
|
-
|
|
695
|
-
reqLists[key] = l.getList(
|
|
465
|
+
_this5.lists.forEach((l, key) => {
|
|
466
|
+
reqLists[key] = l.getList(true);
|
|
696
467
|
});
|
|
697
468
|
var reqBody = {
|
|
698
469
|
lists: reqLists,
|
|
699
470
|
pos: currentPos,
|
|
700
|
-
timeout:
|
|
701
|
-
clientTimeout:
|
|
702
|
-
extensions:
|
|
471
|
+
timeout: _this5.timeoutMS,
|
|
472
|
+
clientTimeout: _this5.timeoutMS + BUFFER_PERIOD_MS,
|
|
473
|
+
extensions: yield _this5.getExtensionRequest(currentPos === undefined)
|
|
703
474
|
};
|
|
704
475
|
// check if we are (un)subscribing to a room and modify request this one time for it
|
|
705
|
-
var newSubscriptions = difference(
|
|
706
|
-
var unsubscriptions = difference(
|
|
476
|
+
var newSubscriptions = difference(_this5.desiredRoomSubscriptions, _this5.confirmedRoomSubscriptions);
|
|
477
|
+
var unsubscriptions = difference(_this5.confirmedRoomSubscriptions, _this5.desiredRoomSubscriptions);
|
|
707
478
|
if (unsubscriptions.size > 0) {
|
|
708
479
|
reqBody.unsubscribe_rooms = Array.from(unsubscriptions);
|
|
709
480
|
}
|
|
710
481
|
if (newSubscriptions.size > 0) {
|
|
711
482
|
reqBody.room_subscriptions = {};
|
|
712
483
|
for (var roomId of newSubscriptions) {
|
|
713
|
-
var customSubName =
|
|
714
|
-
var sub =
|
|
715
|
-
if (customSubName &&
|
|
716
|
-
sub =
|
|
484
|
+
var customSubName = _this5.roomIdToCustomSubscription.get(roomId);
|
|
485
|
+
var sub = _this5.roomSubscriptionInfo;
|
|
486
|
+
if (customSubName && _this5.customSubscriptions.has(customSubName)) {
|
|
487
|
+
sub = _this5.customSubscriptions.get(customSubName);
|
|
717
488
|
}
|
|
718
489
|
reqBody.room_subscriptions[roomId] = sub;
|
|
719
490
|
}
|
|
720
491
|
}
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
_this4.txnId = null;
|
|
724
|
-
}
|
|
725
|
-
_this4.pendingReq = _this4.client.slidingSync(reqBody, _this4.proxyBaseUrl, _this4.abortController.signal);
|
|
726
|
-
resp = yield _this4.pendingReq;
|
|
492
|
+
_this5.pendingReq = _this5.client.slidingSync(reqBody, _this5.proxyBaseUrl, _this5.abortController.signal);
|
|
493
|
+
resp = yield _this5.pendingReq;
|
|
727
494
|
currentPos = resp.pos;
|
|
728
495
|
// update what we think we're subscribed to.
|
|
729
496
|
for (var _roomId of newSubscriptions) {
|
|
730
|
-
|
|
497
|
+
_this5.confirmedRoomSubscriptions.add(_roomId);
|
|
731
498
|
}
|
|
732
499
|
for (var _roomId2 of unsubscriptions) {
|
|
733
|
-
|
|
734
|
-
}
|
|
735
|
-
if (listModifiedCount !== _this4.listModifiedCount) {
|
|
736
|
-
// the lists have been modified whilst we were waiting for 'await' to return, but the abort()
|
|
737
|
-
// call did nothing. It is NOT SAFE to modify the list array now. We'll process the response but
|
|
738
|
-
// not update list pointers.
|
|
739
|
-
logger.debug("list modified during await call, not updating list");
|
|
740
|
-
doNotUpdateList = true;
|
|
500
|
+
_this5.confirmedRoomSubscriptions.delete(_roomId2);
|
|
741
501
|
}
|
|
742
502
|
// mark all these lists as having been sent as sticky so we don't keep sending sticky params
|
|
743
|
-
|
|
503
|
+
_this5.lists.forEach(l => {
|
|
744
504
|
l.setModified(false);
|
|
745
505
|
});
|
|
746
506
|
// set default empty values so we don't need to null check
|
|
@@ -748,25 +508,25 @@ export class SlidingSync extends TypedEventEmitter {
|
|
|
748
508
|
resp.rooms = (_resp$rooms = resp.rooms) !== null && _resp$rooms !== void 0 ? _resp$rooms : {};
|
|
749
509
|
resp.extensions = (_resp$extensions = resp.extensions) !== null && _resp$extensions !== void 0 ? _resp$extensions : {};
|
|
750
510
|
Object.keys(resp.lists).forEach(key => {
|
|
751
|
-
var list =
|
|
511
|
+
var list = _this5.lists.get(key);
|
|
752
512
|
if (!list || !resp) {
|
|
753
513
|
return;
|
|
754
514
|
}
|
|
755
515
|
list.joinedCount = resp.lists[key].count;
|
|
756
516
|
});
|
|
757
|
-
|
|
517
|
+
_this5.invokeLifecycleListeners(SlidingSyncState.RequestFinished, resp);
|
|
758
518
|
} catch (err) {
|
|
759
519
|
if (err.httpStatus) {
|
|
760
|
-
|
|
520
|
+
_this5.invokeLifecycleListeners(SlidingSyncState.RequestFinished, null, err);
|
|
761
521
|
if (err.httpStatus === 400) {
|
|
762
522
|
// session probably expired TODO: assign an errcode
|
|
763
523
|
// so drop state and re-request
|
|
764
|
-
|
|
524
|
+
_this5.resetup();
|
|
765
525
|
currentPos = undefined;
|
|
766
526
|
yield sleep(50); // in case the 400 was for something else; don't tightloop
|
|
767
527
|
return 0; // continue
|
|
768
528
|
} // else fallthrough to generic error handling
|
|
769
|
-
} else if (
|
|
529
|
+
} else if (_this5.needsResend || err.name === "AbortError") {
|
|
770
530
|
return 0; // continue
|
|
771
531
|
// don't sleep as we caused this error by abort()ing the request.
|
|
772
532
|
}
|
|
@@ -776,34 +536,15 @@ export class SlidingSync extends TypedEventEmitter {
|
|
|
776
536
|
if (!resp) {
|
|
777
537
|
return 0; // continue
|
|
778
538
|
}
|
|
779
|
-
yield
|
|
539
|
+
yield _this5.onPreExtensionsResponse(resp.extensions);
|
|
780
540
|
for (var _roomId3 in resp.rooms) {
|
|
781
|
-
yield
|
|
541
|
+
yield _this5.invokeRoomDataListeners(_roomId3, resp.rooms[_roomId3]);
|
|
782
542
|
}
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
for (var [key, list] of Object.entries(resp.lists)) {
|
|
786
|
-
var _list$ops;
|
|
787
|
-
list.ops = (_list$ops = list.ops) !== null && _list$ops !== void 0 ? _list$ops : [];
|
|
788
|
-
if (list.ops.length > 0) {
|
|
789
|
-
listKeysWithUpdates.add(key);
|
|
790
|
-
}
|
|
791
|
-
_this4.processListOps(list, key);
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
_this4.invokeLifecycleListeners(SlidingSyncState.Complete, resp);
|
|
795
|
-
yield _this4.onPostExtensionsResponse(resp.extensions);
|
|
796
|
-
listKeysWithUpdates.forEach(listKey => {
|
|
797
|
-
var list = _this4.lists.get(listKey);
|
|
798
|
-
if (!list) {
|
|
799
|
-
return;
|
|
800
|
-
}
|
|
801
|
-
_this4.emit(SlidingSyncEvent.List, listKey, list.joinedCount, Object.assign({}, list.roomIndexToRoomId));
|
|
802
|
-
});
|
|
803
|
-
_this4.resolveTransactionDefers(resp.txn_id);
|
|
543
|
+
_this5.invokeLifecycleListeners(SlidingSyncState.Complete, resp);
|
|
544
|
+
yield _this5.onPostExtensionsResponse(resp.extensions);
|
|
804
545
|
},
|
|
805
546
|
_ret;
|
|
806
|
-
while (!
|
|
547
|
+
while (!_this5.terminated) {
|
|
807
548
|
_ret = yield* _loop();
|
|
808
549
|
if (_ret === 0) continue;
|
|
809
550
|
}
|