* sliding sync: add client function and add stub sliding-sync.ts
Mostly c/p from sync.ts. Define interfaces for MSC3575 sliding
sync types. Complete WIP!
* Add core sliding sync classes
* Add integration tests for sliding sync api basics
* gut unused code; add more types
* Use SlidingSync in MatrixClient; stub functions for Sync
Enough to make ele-web actually load okay with 0 rooms.
* Start feeding through room data to the client
* Bugfixes so it sorta ish works
* Refactor the public API for sliding sync
Still needs some work but it's a start.
* Use EventEmitter for callbacks. Add ability to adjust lists and listen for list updates.
- Have atomic getList/setList operations on SlidingSync to update windows etc
- Add a list callback which is invoked with the list indicies and joined count.
* Add stub tests; add listenUntil to make tests easier to read
* No need to resend now
* Add more sliding sync tests; add new setListRanges function
* build tests upon one another to reduce boilerplate and c/p
* More thorough sliding sync tests
* Dependency inject SlidingSync in Client opts when calling startClient()
* Linting
* Fix crash when opts is undefined
* Fix up docs to make CI happy
* Remove all listeners when stop()d to allow for GC
* Add support for extensions
* Add ExtensionE2EE automatically if opts.crypto is present
* Add ExtensionToDevice automatically
* Bugfixes for to_device message processing
* default events to []
* bugfix: don't tightloop when the server is down
Caused by not detecting abort() correctly
* Return null for bad index positions
* Add getListData to get the initial calculated list response
* Add is_tombstoned
* More comments
* Add support for account data extension; rejig extension interface
* Handle invite_state
* Feed through prev_batch tokens
* Linting
* Fix tests
* Linting
* Iterate PR
* Iterate tests and remove unused code
* Update matrix-mock-request
* Make tests happier
* Remove DEBUG/debuglog and use logger.debug
* Update the API to the latest MSC; fixup tests
* Use undefined not null to make it work with the latest changes
* Don't recreate rooms when initial: true
* Add defensive code when unsigned.transaction_id is missing
We can still pair up events by looking at the event_id. We need
to do this in Sliding Sync because the proxy has limitations that
means it cannot guarantee it will always incude a transaction_id
in unsigned. The main reason why is due to the following race condition:
- A and B are in a DM room.
- Both are using the proxy.
- A says "hello".
- B's sync stream gets "hello" on the proxy. At this point the proxy
knows it needs to deliver it to A. It does so, but this event has
no transaction_id as it came down B's sync stream, not A's.
- If instead, A's sync stream gets "hello" on the proxy, the proxy
will deliver this message with the transaction_id correctly set.
There are no guarantees that A's sync stream will get the event in a
timely manner, hence the decision to just deliver the events as soon
as the proxy gets the event. This will not be an issue for native
Sliding Sync implementations; this is just a proxy issue.
* Linting
* Add additional sliding sync tests
* Begin adding SlidingSyncSdk tests
* Linting
* Add more sliding sync sdk tests
* Prep work for extension tests
* Linting
* Add account data extension tests
* add to-device tests
* Add E2EE extension tests
* Code smell fixes and extra tests
* Add test for no-txn-id local echo
* Add tests for resolveProfilesToInvites
* Add tests for moving entries down as well as up the list
* Remove conn-management.ts
* Actually verify the event was removed from the txn map
* Handle the case when /sync returns before /send without a txn_id
And ensure all the tests actually test the right things.
* Linting
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
Events returned by the `/sync` endpoint, including relations bundled with other events, may have their `room_id`s stripped out. This causes decryption errors if the IDs aren't repopulated.
Fixesvector-im/element-web#22094.
* Fix test message utils using overload
* Tweak existing tests
* Add test around `MatrixClient::getEventTimeline`
* Fix test to actually exercise the faulty behaviour
* Extract timelineSet thread belongs logic and test it
* tweak method name
Inform the client that historical messages were imported in the timeline and they should refresh the timeline in order to see the new events.
Companion `matrix-react-sdk` PR: https://github.com/matrix-org/matrix-react-sdk/pull/8354
The `marker` events are being used as state now because this way they can't be lost in a timeline gap. Regardless of when they were sent, we will still have the latest version of the state to compare against. Any time we see our latest state value change for marker events, prompt the user that the timeline needs to refresh.
> In a [sync meeting with @ara4n](https://docs.google.com/document/d/1KCEmpnGr4J-I8EeaVQ8QJZKBDu53ViI7V62y5BzfXr0/edit#bookmark=id.67nio1ka8znc), we came up with the idea to make the `marker` events as state events. When the client sees that the `m.room.marker` state changed to a different event ID, it can throw away all of the timeline and re-fetch as needed.
>
> For homeservers where the [same problem](https://github.com/matrix-org/matrix-doc/pull/2716#discussion_r782499674) can happen, we probably don't want to throw away the whole timeline but it can go up the `unsigned.replaces_state` chain of the `m.room.marker` state events to get them all.
>
> In terms of state performance, there could be thousands of `marker` events in a room but it's no different than room members joining and leaving over and over like an IRC room.
>
> *-- https://github.com/matrix-org/matrix-spec-proposals/pull/2716#discussion_r782629097*
### Why are we just setting `timlineNeedsRefresh` (and [prompting the user](https://github.com/matrix-org/matrix-react-sdk/pull/8354)) instead of automatically refreshing the timeline for the user?
If we refreshed the timeline automatically, someone could cause your Element client to constantly refresh the timeline by just sending marker events over and over. Granted, you probably want to leave a room like this 🤷. Perhaps also some sort of DOS vector since everyone will be refreshing and hitting the server at the exact same time.
In order to avoid the timeline maybe going blank during the refresh, we could re-fetch the new events first, then replace the timeline. But the points above still stand on why we shouldn't.
* Update jest monorepo
* -w
* Fix guest rooms test to use async/await instead of a done callback
The done callback was never being called because it relies on a `process.nextTick()` deep within the mock. For this test we don't get a "next tick" because the event loop is busy, so we instead cargocult some test infrastructure from surrounding tests and verify the expected API call was cleared from the queue.
* Enable github-actions reporter
* Don't override local reporters
* Stop DeviceLists at end of tests
* stop more clients
* Fix tests and DRY typing
* Fix client/crypto stopping in tests
* Fix Buffer c'tor deprecated warnings
* Fix devicelist-integ test being excluded due to poor naming
Co-authored-by: Renovate Bot <bot@renovateapp.com>
Co-authored-by: Travis Ralston <travisr@matrix.org>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
* More sonar tweaks and typing improvements
* delint
* Write some tests
* Attempt to make TS happy
* Stash tests
* Add tests
* Add `istanbul ignore if` around logging special-case for test env
* Add test
* Comments
* Parse extensible events on demand
* Decorate messages with MSC1767 when appropriate
We do this automatically to force a pool of messages in the wild we can use for testing.
* Include the SDK
* Appease linter and tests
* Change property name to appease linter
* Update SDK
- throw an AbortError when aborting is detected
- don't turn AbortError's into a ConnectionError
- also consider the string "aborted" an AbortError for unit tests
- unit tests like to reject the request with a MatrixError,
so exclude those too
Now that we're pointing at `src/` for tests, we can stop trying to load source maps from random places. With this dependency used, source maps are off by a few lines.