* This should fix the problem where we could end up with two concurrent syncs
due to both retrying /sync and hitting /versions. There is now one and only
one mechanism for connection recovery.
* Hit /versions a little less often as I think every 2 seconds is a little
over-aggressive. Also introduce randomness to minimize possibility of
thundering herds.
* Add a listener for the 'online' event in case any browser is nice enough
to ever fire it.
* Treat a 400 response from /versions as successful since older synapses
will not support it.
When we reset the live timeline due to a limited sync, stash next_batch as the
pagination token so that we can work forward to the new live timeline.
(Note that this requires matrix-org/synapse#535)
The peek code needs to make sure it sets the pagination token /after/ adding
the events to the timeline, otherwise it will get reset when the events
are added.
When a /sync request fails, we spin up a keep-alive poll to /_matrix/client/r0
which 400s. We treat any HTTP response code as a success for the purposes of
polling the server. When a successful poll is done, we shoot the current /sync
request in the head immediately (via a hacky abort() on the promise) and retry
the /sync.
This provides optional support for fetching old events via the /context API,
and paginating backwards and forwards from them, eventually merging into the
live timeline.
To support it, events are now stored in an EventTimeline, rather than directly
in an array in the Room; the old names are maintained as references for
compatibility.
The feature has to be enabled explicitly, otherwise it would be impossible for
existing clients to back-paginate to the old events after a gappy /sync.
Still TODO here:
* An object which provides a window into the timelines to make them possible to
use. This will be a separate PR.
* Rewrite the 'EventContext' used by the searchRoomEvents API in terms of an
EventTimeline - it is essentially a subset.
After much discussion, the HS will now behave the same for guests/non-guests
wrt joining a room (you get the entire room state on join). This leave "peeking"
which never triggers a join. This can be implemented for guests by doing a
room initial sync followed by a specific /events poll with a specific room_id.
This means there are 2 sync streams: /sync and the peek /events. Architected
so you can only have 1 peek stream in progress at a time (if this were arbitrary
we'd quickly run into concurrent in-flight browser request limits (5).