1
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
|
import { MatrixClient } from "./client";
import { IRoomEvent, IStateEvent } from "./sync-accumulator";
import { TypedEventEmitter } from "./models/typed-event-emitter";
export declare const MSC3575_WILDCARD = "*";
export declare const MSC3575_STATE_KEY_ME = "$ME";
export declare const MSC3575_STATE_KEY_LAZY = "$LAZY";
/**
* Represents a subscription to a room or set of rooms. Controls which events are returned.
*/
export interface MSC3575RoomSubscription {
required_state?: string[][];
timeline_limit?: number;
include_old_rooms?: MSC3575RoomSubscription;
}
/**
* Controls which rooms are returned in a given list.
*/
export interface MSC3575Filter {
is_dm?: boolean;
is_encrypted?: boolean;
is_invite?: boolean;
room_name_like?: string;
room_types?: string[];
not_room_types?: string[];
spaces?: string[];
tags?: string[];
not_tags?: string[];
}
/**
* Represents a list subscription.
*/
export interface MSC3575List extends MSC3575RoomSubscription {
ranges: number[][];
sort?: string[];
filters?: MSC3575Filter;
slow_get_all_rooms?: boolean;
}
/**
* A complete Sliding Sync request.
*/
export interface MSC3575SlidingSyncRequest {
lists?: Record<string, MSC3575List>;
unsubscribe_rooms?: string[];
room_subscriptions?: Record<string, MSC3575RoomSubscription>;
extensions?: object;
txn_id?: string;
pos?: string;
timeout?: number;
clientTimeout?: number;
}
export interface MSC3575RoomData {
name: string;
required_state: IStateEvent[];
timeline: (IRoomEvent | IStateEvent)[];
notification_count?: number;
highlight_count?: number;
joined_count?: number;
invited_count?: number;
invite_state?: IStateEvent[];
initial?: boolean;
limited?: boolean;
is_dm?: boolean;
prev_batch?: string;
num_live?: number;
}
interface ListResponse {
count: number;
ops: Operation[];
}
interface BaseOperation {
op: string;
}
interface DeleteOperation extends BaseOperation {
op: "DELETE";
index: number;
}
interface InsertOperation extends BaseOperation {
op: "INSERT";
index: number;
room_id: string;
}
interface InvalidateOperation extends BaseOperation {
op: "INVALIDATE";
range: [number, number];
}
interface SyncOperation extends BaseOperation {
op: "SYNC";
range: [number, number];
room_ids: string[];
}
type Operation = DeleteOperation | InsertOperation | InvalidateOperation | SyncOperation;
/**
* A complete Sliding Sync response
*/
export interface MSC3575SlidingSyncResponse {
pos: string;
txn_id?: string;
lists: Record<string, ListResponse>;
rooms: Record<string, MSC3575RoomData>;
extensions: Record<string, object>;
}
export declare enum SlidingSyncState {
/**
* Fired by SlidingSyncEvent.Lifecycle event immediately before processing the response.
*/
RequestFinished = "FINISHED",
/**
* Fired by SlidingSyncEvent.Lifecycle event immediately after all room data listeners have been
* invoked, but before list listeners.
*/
Complete = "COMPLETE"
}
/**
* When onResponse extensions should be invoked: before or after processing the main response.
*/
export declare enum ExtensionState {
PreProcess = "ExtState.PreProcess",
PostProcess = "ExtState.PostProcess"
}
/**
* An interface that must be satisfied to register extensions
*/
export interface Extension<Req extends {}, Res extends {}> {
/**
* The extension name to go under 'extensions' in the request body.
* @returns The JSON key.
*/
name(): string;
/**
* A function which is called when the request JSON is being formed.
* Returns the data to insert under this key.
* @param isInitial - True when this is part of the initial request (send sticky params)
* @returns The request JSON to send.
*/
onRequest(isInitial: boolean): Req | undefined;
/**
* A function which is called when there is response JSON under this extension.
* @param data - The response JSON under the extension name.
*/
onResponse(data: Res): void;
/**
* Controls when onResponse should be called.
* @returns The state when it should be called.
*/
when(): ExtensionState;
}
/**
* Events which can be fired by the SlidingSync class. These are designed to provide different levels
* of information when processing sync responses.
* - RoomData: concerns rooms, useful for SlidingSyncSdk to update its knowledge of rooms.
* - Lifecycle: concerns callbacks at various well-defined points in the sync process.
* - List: concerns lists, useful for UI layers to re-render room lists.
* Specifically, the order of event invocation is:
* - Lifecycle (state=RequestFinished)
* - RoomData (N times)
* - Lifecycle (state=Complete)
* - List (at most once per list)
*/
export declare enum SlidingSyncEvent {
/**
* This event fires when there are updates for a room. Fired as and when rooms are encountered
* in the response.
*/
RoomData = "SlidingSync.RoomData",
/**
* This event fires at various points in the /sync loop lifecycle.
* - SlidingSyncState.RequestFinished: Fires after we receive a valid response but before the
* response has been processed. Perform any pre-process steps here. If there was a problem syncing,
* `err` will be set (e.g network errors).
* - SlidingSyncState.Complete: Fires after all SlidingSyncEvent.RoomData have been fired but before
* SlidingSyncEvent.List.
*/
Lifecycle = "SlidingSync.Lifecycle",
/**
* This event fires whenever there has been a change to this list index. It fires exactly once
* per list, even if there were multiple operations for the list.
* It fires AFTER Lifecycle and RoomData events.
*/
List = "SlidingSync.List"
}
export type SlidingSyncEventHandlerMap = {
[SlidingSyncEvent.RoomData]: (roomId: string, roomData: MSC3575RoomData) => void;
[SlidingSyncEvent.Lifecycle]: (state: SlidingSyncState, resp: MSC3575SlidingSyncResponse | null, err?: Error) => void;
[SlidingSyncEvent.List]: (listKey: string, joinedCount: number, roomIndexToRoomId: Record<number, string>) => void;
};
/**
* SlidingSync is a high-level data structure which controls the majority of sliding sync.
* It has no hooks into JS SDK except for needing a MatrixClient to perform the HTTP request.
* This means this class (and everything it uses) can be used in isolation from JS SDK if needed.
* To hook this up with the JS SDK, you need to use SlidingSyncSdk.
*/
export declare class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSyncEventHandlerMap> {
private readonly proxyBaseUrl;
private roomSubscriptionInfo;
private readonly client;
private readonly timeoutMS;
private lists;
private listModifiedCount;
private terminated;
private needsResend;
private txnId;
private txnIdDefers;
private extensions;
private desiredRoomSubscriptions;
private confirmedRoomSubscriptions;
private customSubscriptions;
private roomIdToCustomSubscription;
private pendingReq?;
private abortController?;
/**
* Create a new sliding sync instance
* @param proxyBaseUrl - The base URL of the sliding sync proxy
* @param lists - The lists to use for sliding sync.
* @param roomSubscriptionInfo - The params to use for room subscriptions.
* @param client - The client to use for /sync calls.
* @param timeoutMS - The number of milliseconds to wait for a response.
*/
constructor(proxyBaseUrl: string, lists: Map<string, MSC3575List>, roomSubscriptionInfo: MSC3575RoomSubscription, client: MatrixClient, timeoutMS: number);
/**
* Add a custom room subscription, referred to by an arbitrary name. If a subscription with this
* name already exists, it is replaced. No requests are sent by calling this method.
* @param name - The name of the subscription. Only used to reference this subscription in
* useCustomSubscription.
* @param sub - The subscription information.
*/
addCustomSubscription(name: string, sub: MSC3575RoomSubscription): void;
/**
* Use a custom subscription previously added via addCustomSubscription. No requests are sent
* by calling this method. Use modifyRoomSubscriptions to resend subscription information.
* @param roomId - The room to use the subscription in.
* @param name - The name of the subscription. If this name is unknown, the default subscription
* will be used.
*/
useCustomSubscription(roomId: string, name: string): void;
/**
* Get the room index data for a list.
* @param key - The list key
* @returns The list data which contains the rooms in this list
*/
getListData(key: string): {
joinedCount: number;
roomIndexToRoomId: Record<number, string>;
} | null;
/**
* Get the full request list parameters for a list index. This function is provided for callers to use
* in conjunction with setList to update fields on an existing list.
* @param key - The list key to get the params for.
* @returns A copy of the list params or undefined.
*/
getListParams(key: string): MSC3575List | null;
/**
* Set new ranges for an existing list. Calling this function when _only_ the ranges have changed
* is more efficient than calling setList(index,list) as this function won't resend sticky params,
* whereas setList always will.
* @param key - The list key to modify
* @param ranges - The new ranges to apply.
* @returns A promise which resolves to the transaction ID when it has been received down sync
* (or rejects with the transaction ID if the action was not applied e.g the request was cancelled
* immediately after sending, in which case the action will be applied in the subsequent request)
*/
setListRanges(key: string, ranges: number[][]): Promise<string>;
/**
* Add or replace a list. Calling this function will interrupt the /sync request to resend new
* lists.
* @param key - The key to modify
* @param list - The new list parameters.
* @returns A promise which resolves to the transaction ID when it has been received down sync
* (or rejects with the transaction ID if the action was not applied e.g the request was cancelled
* immediately after sending, in which case the action will be applied in the subsequent request)
*/
setList(key: string, list: MSC3575List): Promise<string>;
/**
* Get the room subscriptions for the sync API.
* @returns A copy of the desired room subscriptions.
*/
getRoomSubscriptions(): Set<string>;
/**
* Modify the room subscriptions for the sync API. Calling this function will interrupt the
* /sync request to resend new subscriptions. If the /sync stream has not started, this will
* prepare the room subscriptions for when start() is called.
* @param s - The new desired room subscriptions.
* @returns A promise which resolves to the transaction ID when it has been received down sync
* (or rejects with the transaction ID if the action was not applied e.g the request was cancelled
* immediately after sending, in which case the action will be applied in the subsequent request)
*/
modifyRoomSubscriptions(s: Set<string>): Promise<string>;
/**
* Modify which events to retrieve for room subscriptions. Invalidates all room subscriptions
* such that they will be sent up afresh.
* @param rs - The new room subscription fields to fetch.
* @returns A promise which resolves to the transaction ID when it has been received down sync
* (or rejects with the transaction ID if the action was not applied e.g the request was cancelled
* immediately after sending, in which case the action will be applied in the subsequent request)
*/
modifyRoomSubscriptionInfo(rs: MSC3575RoomSubscription): Promise<string>;
/**
* Register an extension to send with the /sync request.
* @param ext - The extension to register.
*/
registerExtension(ext: Extension<any, any>): void;
private getExtensionRequest;
private onPreExtensionsResponse;
private onPostExtensionsResponse;
/**
* Invoke all attached room data listeners.
* @param roomId - The room which received some data.
* @param roomData - The raw sliding sync response JSON.
*/
private invokeRoomDataListeners;
/**
* Invoke all attached lifecycle listeners.
* @param state - The Lifecycle state
* @param resp - The raw sync response JSON
* @param err - Any error that occurred when making the request e.g. network errors.
*/
private invokeLifecycleListeners;
private shiftRight;
private shiftLeft;
private removeEntry;
private addEntry;
private processListOps;
/**
* Resend a Sliding Sync request. Used when something has changed in the request. Resolves with
* the transaction ID of this request on success. Rejects with the transaction ID of this request
* on failure.
*/
resend(): Promise<string>;
private resolveTransactionDefers;
/**
* Stop syncing with the server.
*/
stop(): void;
/**
* Re-setup this connection e.g in the event of an expired session.
*/
private resetup;
/**
* Start syncing with the server. Blocks until stopped.
*/
start(): Promise<void>;
}
export {};
//# sourceMappingURL=sliding-sync.d.ts.map
|