hydrogen-web/src/matrix/SessionContainer.js

96 lines
2.8 KiB
JavaScript
Raw Normal View History

2020-04-10 02:49:49 +05:30
const factory = {
Clock: () => new DOMClock(),
Request: () => fetchRequest,
Online: () => new DOMOnline(),
HomeServerApi: ()
}
export const LoadState = createEnum(
"Loading",
"InitialSync",
"Migrating", //not used atm, but would fit here
"Error",
"Ready",
);
class SessionContainer extends ObservableValue {
constructor({clock, random, isOnline, request, storageFactory, factory}) {
this.disposables = new Disposables();
}
dispose() {
this.disposables.dispose();
}
get state() {
return this._state;
}
_setState(state) {
if (state !== this._state) {
const previousState = this._state;
this._state = state;
this.emit(previousState);
}
}
get sync() {
return this._sync;
}
get session() {
return this._session;
}
_createReconnector() {
const reconnector = new Reconnector(
new ExponentialRetryDelay(2000, this._clock.createTimeout),
this._clock.createMeasure
);
// retry connection immediatly when online is detected
this.disposables.track(isOnline.subscribe(online => {
if(online) {
reconnector.tryNow();
}
}));
return reconnector;
}
async start(sessionInfo) {
try {
this._setState(LoadState.Loading);
this._reconnector = this._createReconnector();
const hsApi = this._createHsApi(sessionInfo.homeServer, sessionInfo.accessToken, this._reconnector);
const storage = await this._storageFactory.create(sessionInfo.id);
// no need to pass access token to session
const filteredSessionInfo = {
deviceId: sessionInfo.deviceId,
userId: sessionInfo.userId,
homeServer: sessionInfo.homeServer,
};
this._session = new Session({storage, sessionInfo: filteredSessionInfo, hsApi});
await this._session.load();
this._sync = new Sync({hsApi, storage, this._session});
// notify sync and session when back online
this.disposables.track(reconnector.subscribe(state => {
this._sync.start();
session.notifyNetworkAvailable(reconnector.lastVersionsResponse);
}));
const needsInitialSync = !this._session.syncToken;
if (!needsInitialSync) {
this._setState(LoadState.Ready);
} else {
this._setState(LoadState.InitialSync);
}
await this._sync.start();
this._setState(LoadState.Ready);
this._session.notifyNetworkAvailable();
} catch (err) {
this._error = err;
this._setState(LoadState.Error);
}
}
}