From 5d4454734af5a03bfa186b441a23512cef0f9b90 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Wed, 11 Aug 2021 14:22:17 -0700 Subject: [PATCH 01/15] Migrate RoomStateStore.js to TypeScript --- src/matrix/storage/idb/Transaction.js | 2 +- .../{RoomStateStore.js => RoomStateStore.ts} | 22 ++++++++++++++----- 2 files changed, 17 insertions(+), 7 deletions(-) rename src/matrix/storage/idb/stores/{RoomStateStore.js => RoomStateStore.ts} (68%) diff --git a/src/matrix/storage/idb/Transaction.js b/src/matrix/storage/idb/Transaction.js index 71513730..4a7b66fe 100644 --- a/src/matrix/storage/idb/Transaction.js +++ b/src/matrix/storage/idb/Transaction.js @@ -22,7 +22,7 @@ import {RoomSummaryStore} from "./stores/RoomSummaryStore"; import {InviteStore} from "./stores/InviteStore"; import {TimelineEventStore} from "./stores/TimelineEventStore"; import {TimelineRelationStore} from "./stores/TimelineRelationStore"; -import {RoomStateStore} from "./stores/RoomStateStore.js"; +import {RoomStateStore} from "./stores/RoomStateStore"; import {RoomMemberStore} from "./stores/RoomMemberStore"; import {TimelineFragmentStore} from "./stores/TimelineFragmentStore.js"; import {PendingEventStore} from "./stores/PendingEventStore.js"; diff --git a/src/matrix/storage/idb/stores/RoomStateStore.js b/src/matrix/storage/idb/stores/RoomStateStore.ts similarity index 68% rename from src/matrix/storage/idb/stores/RoomStateStore.js rename to src/matrix/storage/idb/stores/RoomStateStore.ts index db54458f..d88240a7 100644 --- a/src/matrix/storage/idb/stores/RoomStateStore.js +++ b/src/matrix/storage/idb/stores/RoomStateStore.ts @@ -16,31 +16,41 @@ limitations under the License. */ import {MAX_UNICODE} from "./common"; +import {Store} from "../Store"; +import {StateEvent} from "../../types"; -function encodeKey(roomId, eventType, stateKey) { +function encodeKey(roomId: string, eventType: string, stateKey: string) { return `${roomId}|${eventType}|${stateKey}`; } +export interface RoomStateEntry { + roomId: string; + event: StateEvent; + key: string; +} + export class RoomStateStore { - constructor(idbStore) { + private _roomStateStore: Store; + + constructor(idbStore: Store) { this._roomStateStore = idbStore; } - get(roomId, type, stateKey) { + get(roomId: string, type: string, stateKey: string): Promise { const key = encodeKey(roomId, type, stateKey); return this._roomStateStore.get(key); } - set(roomId, event) { + set(roomId: string, event: StateEvent): Promise { const key = encodeKey(roomId, event.type, event.state_key); const entry = {roomId, event, key}; return this._roomStateStore.put(entry); } - removeAllForRoom(roomId) { + removeAllForRoom(roomId: string): Promise { // exclude both keys as they are theoretical min and max, // but we should't have a match for just the room id, or room id with max const range = this._roomStateStore.IDBKeyRange.bound(roomId, `${roomId}|${MAX_UNICODE}`, true, true); - this._roomStateStore.delete(range); + return this._roomStateStore.delete(range); } } From 33d94b9497e070e6cc2207080a881ef54140e3a2 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Thu, 12 Aug 2021 10:33:05 -0700 Subject: [PATCH 02/15] Migrate OutboundGroupSessionStore to TypeScript --- src/matrix/storage/idb/Transaction.js | 2 +- ...nStore.js => OutboundGroupSessionStore.ts} | 21 +++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) rename src/matrix/storage/idb/stores/{OutboundGroupSessionStore.js => OutboundGroupSessionStore.ts} (60%) diff --git a/src/matrix/storage/idb/Transaction.js b/src/matrix/storage/idb/Transaction.js index 4a7b66fe..092bbb05 100644 --- a/src/matrix/storage/idb/Transaction.js +++ b/src/matrix/storage/idb/Transaction.js @@ -30,7 +30,7 @@ import {UserIdentityStore} from "./stores/UserIdentityStore.js"; import {DeviceIdentityStore} from "./stores/DeviceIdentityStore.js"; import {OlmSessionStore} from "./stores/OlmSessionStore.js"; import {InboundGroupSessionStore} from "./stores/InboundGroupSessionStore.js"; -import {OutboundGroupSessionStore} from "./stores/OutboundGroupSessionStore.js"; +import {OutboundGroupSessionStore} from "./stores/OutboundGroupSessionStore"; import {GroupSessionDecryptionStore} from "./stores/GroupSessionDecryptionStore.js"; import {OperationStore} from "./stores/OperationStore.js"; import {AccountDataStore} from "./stores/AccountDataStore.js"; diff --git a/src/matrix/storage/idb/stores/OutboundGroupSessionStore.js b/src/matrix/storage/idb/stores/OutboundGroupSessionStore.ts similarity index 60% rename from src/matrix/storage/idb/stores/OutboundGroupSessionStore.js rename to src/matrix/storage/idb/stores/OutboundGroupSessionStore.ts index 9710765f..5a33ec2c 100644 --- a/src/matrix/storage/idb/stores/OutboundGroupSessionStore.js +++ b/src/matrix/storage/idb/stores/OutboundGroupSessionStore.ts @@ -13,21 +13,30 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ +import {Store} from "../Store"; + +interface OutboundSession { + roomId: string; + session: string; + createdAt: number; +} export class OutboundGroupSessionStore { - constructor(store) { + private _store: Store; + + constructor(store: Store) { this._store = store; } - remove(roomId) { - this._store.delete(roomId); + remove(roomId: string): Promise { + return this._store.delete(roomId); } - get(roomId) { + get(roomId: string): Promise { return this._store.get(roomId); } - set(session) { - this._store.put(session); + set(session: OutboundSession): Promise { + return this._store.put(session); } } From 8c966627bc92aeb3dba3c0e00d13524dc36c55de Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Thu, 12 Aug 2021 10:41:58 -0700 Subject: [PATCH 03/15] Migrate GroupSessionDecryptionStore to TypeScript --- src/matrix/storage/idb/Transaction.js | 2 +- ...tore.js => GroupSessionDecryptionStore.ts} | 23 +++++++++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) rename src/matrix/storage/idb/stores/{GroupSessionDecryptionStore.js => GroupSessionDecryptionStore.ts} (61%) diff --git a/src/matrix/storage/idb/Transaction.js b/src/matrix/storage/idb/Transaction.js index 092bbb05..8b19af37 100644 --- a/src/matrix/storage/idb/Transaction.js +++ b/src/matrix/storage/idb/Transaction.js @@ -31,7 +31,7 @@ import {DeviceIdentityStore} from "./stores/DeviceIdentityStore.js"; import {OlmSessionStore} from "./stores/OlmSessionStore.js"; import {InboundGroupSessionStore} from "./stores/InboundGroupSessionStore.js"; import {OutboundGroupSessionStore} from "./stores/OutboundGroupSessionStore"; -import {GroupSessionDecryptionStore} from "./stores/GroupSessionDecryptionStore.js"; +import {GroupSessionDecryptionStore} from "./stores/GroupSessionDecryptionStore"; import {OperationStore} from "./stores/OperationStore.js"; import {AccountDataStore} from "./stores/AccountDataStore.js"; diff --git a/src/matrix/storage/idb/stores/GroupSessionDecryptionStore.js b/src/matrix/storage/idb/stores/GroupSessionDecryptionStore.ts similarity index 61% rename from src/matrix/storage/idb/stores/GroupSessionDecryptionStore.js rename to src/matrix/storage/idb/stores/GroupSessionDecryptionStore.ts index da47639d..a55bf66b 100644 --- a/src/matrix/storage/idb/stores/GroupSessionDecryptionStore.js +++ b/src/matrix/storage/idb/stores/GroupSessionDecryptionStore.ts @@ -15,30 +15,39 @@ limitations under the License. */ import {MIN_UNICODE, MAX_UNICODE} from "./common"; +import {Store} from "../Store"; -function encodeKey(roomId, sessionId, messageIndex) { +function encodeKey(roomId: string, sessionId: string, messageIndex: number | string): string { return `${roomId}|${sessionId}|${messageIndex}`; } +interface GroupSessionDecryption { + eventId: string; + timestamp: number; + key: string; +} + export class GroupSessionDecryptionStore { - constructor(store) { + private _store: Store; + + constructor(store: Store) { this._store = store; } - get(roomId, sessionId, messageIndex) { + get(roomId: string, sessionId: string, messageIndex: number): Promise { return this._store.get(encodeKey(roomId, sessionId, messageIndex)); } - set(roomId, sessionId, messageIndex, decryption) { + set(roomId: string, sessionId: string, messageIndex: number, decryption: GroupSessionDecryption): Promise { decryption.key = encodeKey(roomId, sessionId, messageIndex); - this._store.put(decryption); + return this._store.put(decryption); } - removeAllForRoom(roomId) { + removeAllForRoom(roomId: string): Promise { const range = this._store.IDBKeyRange.bound( encodeKey(roomId, MIN_UNICODE, MIN_UNICODE), encodeKey(roomId, MAX_UNICODE, MAX_UNICODE) ); - this._store.delete(range); + return this._store.delete(range); } } From 77f75fd968349c3e47ca2205301d7373942f4c02 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Thu, 12 Aug 2021 11:05:55 -0700 Subject: [PATCH 04/15] Migrate OperationStore to TypeScript --- src/matrix/storage/idb/Transaction.js | 2 +- src/matrix/storage/idb/schema.js | 2 +- .../{OperationStore.js => OperationStore.ts} | 45 ++++++++++++++----- 3 files changed, 35 insertions(+), 14 deletions(-) rename src/matrix/storage/idb/stores/{OperationStore.js => OperationStore.ts} (60%) diff --git a/src/matrix/storage/idb/Transaction.js b/src/matrix/storage/idb/Transaction.js index 8b19af37..7d5f8af9 100644 --- a/src/matrix/storage/idb/Transaction.js +++ b/src/matrix/storage/idb/Transaction.js @@ -32,7 +32,7 @@ import {OlmSessionStore} from "./stores/OlmSessionStore.js"; import {InboundGroupSessionStore} from "./stores/InboundGroupSessionStore.js"; import {OutboundGroupSessionStore} from "./stores/OutboundGroupSessionStore"; import {GroupSessionDecryptionStore} from "./stores/GroupSessionDecryptionStore"; -import {OperationStore} from "./stores/OperationStore.js"; +import {OperationStore} from "./stores/OperationStore"; import {AccountDataStore} from "./stores/AccountDataStore.js"; export class Transaction { diff --git a/src/matrix/storage/idb/schema.js b/src/matrix/storage/idb/schema.js index d0d9cf16..7df2cb3e 100644 --- a/src/matrix/storage/idb/schema.js +++ b/src/matrix/storage/idb/schema.js @@ -2,7 +2,7 @@ import {iterateCursor, reqAsPromise} from "./utils"; import {RoomMember, EVENT_TYPE as MEMBER_EVENT_TYPE} from "../../room/members/RoomMember.js"; import {RoomMemberStore} from "./stores/RoomMemberStore"; import {SessionStore} from "./stores/SessionStore"; -import {encodeScopeTypeKey} from "./stores/OperationStore.js"; +import {encodeScopeTypeKey} from "./stores/OperationStore"; // FUNCTIONS SHOULD ONLY BE APPENDED!! // the index in the array is the database version diff --git a/src/matrix/storage/idb/stores/OperationStore.js b/src/matrix/storage/idb/stores/OperationStore.ts similarity index 60% rename from src/matrix/storage/idb/stores/OperationStore.js rename to src/matrix/storage/idb/stores/OperationStore.ts index 961e36af..2be6c3d7 100644 --- a/src/matrix/storage/idb/stores/OperationStore.js +++ b/src/matrix/storage/idb/stores/OperationStore.ts @@ -14,23 +14,43 @@ See the License for the specific language governing permissions and limitations under the License. */ import {MIN_UNICODE, MAX_UNICODE} from "./common"; +import {Store} from "../Store"; -export function encodeScopeTypeKey(scope, type) { +export function encodeScopeTypeKey(scope: string, type: string): string { return `${scope}|${type}`; } +interface Operation { + id: string; + type: string; + scope: string; + userIds: string[]; + scopeTypeKey: string; + roomKeyMessage: RoomKeyMessage; +} + +interface RoomKeyMessage { + room_id: string; + session_id: string; + session_key: string; + algorithm: string; + chain_index: number; +} + export class OperationStore { - constructor(store) { + private _store: Store; + + constructor(store: Store) { this._store = store; } - getAll() { + getAll(): Promise { return this._store.selectAll(); } - async getAllByTypeAndScope(type, scope) { + async getAllByTypeAndScope(type: string, scope: string): Promise { const key = encodeScopeTypeKey(scope, type); - const results = []; + const results: Operation[] = []; await this._store.index("byScopeAndType").iterateWhile(key, value => { if (value.scopeTypeKey !== key) { return false; @@ -41,20 +61,20 @@ export class OperationStore { return results; } - add(operation) { + add(operation: Operation): Promise { operation.scopeTypeKey = encodeScopeTypeKey(operation.scope, operation.type); - this._store.add(operation); + return this._store.add(operation); } - update(operation) { - this._store.put(operation); + update(operation: Operation): Promise { + return this._store.put(operation); } - remove(id) { - this._store.delete(id); + remove(id: string): Promise { + return this._store.delete(id); } - async removeAllForScope(scope) { + async removeAllForScope(scope: string): Promise { const range = this._store.IDBKeyRange.bound( encodeScopeTypeKey(scope, MIN_UNICODE), encodeScopeTypeKey(scope, MAX_UNICODE) @@ -64,5 +84,6 @@ export class OperationStore { cur.delete(); return true; }); + return; } } From 742ab280992941498360e367ac64f4935e18fb57 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Thu, 12 Aug 2021 12:37:47 -0700 Subject: [PATCH 05/15] Migrate AccountDataStore.js to TypeScript. --- src/matrix/storage/idb/Transaction.js | 2 +- ...ccountDataStore.js => AccountDataStore.ts} | 27 ++++++++++++------- 2 files changed, 19 insertions(+), 10 deletions(-) rename src/matrix/storage/idb/stores/{AccountDataStore.js => AccountDataStore.ts} (55%) diff --git a/src/matrix/storage/idb/Transaction.js b/src/matrix/storage/idb/Transaction.js index 7d5f8af9..23037195 100644 --- a/src/matrix/storage/idb/Transaction.js +++ b/src/matrix/storage/idb/Transaction.js @@ -33,7 +33,7 @@ import {InboundGroupSessionStore} from "./stores/InboundGroupSessionStore.js"; import {OutboundGroupSessionStore} from "./stores/OutboundGroupSessionStore"; import {GroupSessionDecryptionStore} from "./stores/GroupSessionDecryptionStore"; import {OperationStore} from "./stores/OperationStore"; -import {AccountDataStore} from "./stores/AccountDataStore.js"; +import {AccountDataStore} from "./stores/AccountDataStore"; export class Transaction { constructor(txn, allowedStoreNames, IDBKeyRange) { diff --git a/src/matrix/storage/idb/stores/AccountDataStore.js b/src/matrix/storage/idb/stores/AccountDataStore.ts similarity index 55% rename from src/matrix/storage/idb/stores/AccountDataStore.js rename to src/matrix/storage/idb/stores/AccountDataStore.ts index 7f22a518..7538c53e 100644 --- a/src/matrix/storage/idb/stores/AccountDataStore.js +++ b/src/matrix/storage/idb/stores/AccountDataStore.ts @@ -13,17 +13,26 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ +import {Store} from "../Store"; +import {Content} from "../../types"; + +interface AccountDataEntry { + type: string; + content: Content; +} export class AccountDataStore { - constructor(store) { - this._store = store; - } + private _store: Store; - async get(type) { - return await this._store.get(type); - } + constructor(store: Store) { + this._store = store; + } - set(event) { - return this._store.put(event); - } + async get(type: string): Promise { + return await this._store.get(type); + } + + set(event: AccountDataEntry): Promise { + return this._store.put(event); + } } From fad6d63c147e952acc74fb6c1ce2038c100f9237 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Wed, 11 Aug 2021 15:35:28 -0700 Subject: [PATCH 06/15] Migrate TimelineFragmentStore.js to TypeScript --- src/matrix/storage/idb/Transaction.js | 2 +- ...gmentStore.js => TimelineFragmentStore.ts} | 40 +++++++++++++------ 2 files changed, 28 insertions(+), 14 deletions(-) rename src/matrix/storage/idb/stores/{TimelineFragmentStore.js => TimelineFragmentStore.ts} (68%) diff --git a/src/matrix/storage/idb/Transaction.js b/src/matrix/storage/idb/Transaction.js index 23037195..43f26cd2 100644 --- a/src/matrix/storage/idb/Transaction.js +++ b/src/matrix/storage/idb/Transaction.js @@ -24,7 +24,7 @@ import {TimelineEventStore} from "./stores/TimelineEventStore"; import {TimelineRelationStore} from "./stores/TimelineRelationStore"; import {RoomStateStore} from "./stores/RoomStateStore"; import {RoomMemberStore} from "./stores/RoomMemberStore"; -import {TimelineFragmentStore} from "./stores/TimelineFragmentStore.js"; +import {TimelineFragmentStore} from "./stores/TimelineFragmentStore"; import {PendingEventStore} from "./stores/PendingEventStore.js"; import {UserIdentityStore} from "./stores/UserIdentityStore.js"; import {DeviceIdentityStore} from "./stores/DeviceIdentityStore.js"; diff --git a/src/matrix/storage/idb/stores/TimelineFragmentStore.js b/src/matrix/storage/idb/stores/TimelineFragmentStore.ts similarity index 68% rename from src/matrix/storage/idb/stores/TimelineFragmentStore.js rename to src/matrix/storage/idb/stores/TimelineFragmentStore.ts index 07a8ff42..cb89211a 100644 --- a/src/matrix/storage/idb/stores/TimelineFragmentStore.js +++ b/src/matrix/storage/idb/stores/TimelineFragmentStore.ts @@ -17,17 +17,31 @@ limitations under the License. import { StorageError } from "../../common"; import {KeyLimits} from "../../common"; import { encodeUint32 } from "../utils"; +import {Store} from "../Store"; -function encodeKey(roomId, fragmentId) { +interface Fragment { + roomId: string; + id: number; + previousId: number | null; + nextId: number | null; + previousToken: string | null; + nextToken: string | null; +} + +type FragmentEntry = Fragment & { key: string } + +function encodeKey(roomId: string, fragmentId: number): string { return `${roomId}|${encodeUint32(fragmentId)}`; } export class TimelineFragmentStore { - constructor(store) { + private _store: Store; + + constructor(store: Store) { this._store = store; } - _allRange(roomId) { + _allRange(roomId: string): IDBKeyRange { try { return this._store.IDBKeyRange.bound( encodeKey(roomId, KeyLimits.minStorageKey), @@ -38,13 +52,13 @@ export class TimelineFragmentStore { } } - all(roomId) { + all(roomId: string): Promise { return this._store.selectAll(this._allRange(roomId)); } /** Returns the fragment without a nextToken and without nextId, if any, with the largest id if there are multiple (which should not happen) */ - liveFragment(roomId) { + liveFragment(roomId: string): Promise { // why do we need this? // Ok, take the case where you've got a /context fragment and a /sync fragment // They are not connected. So, upon loading the persister, which one do we take? We can't sort them ... @@ -60,20 +74,20 @@ export class TimelineFragmentStore { // should generate an id an return it? // depends if we want to do anything smart with fragment ids, // like give them meaning depending on range. not for now probably ... - add(fragment) { - fragment.key = encodeKey(fragment.roomId, fragment.id); - this._store.add(fragment); + add(fragment: Fragment): Promise { + (fragment as any).key = encodeKey(fragment.roomId, fragment.id); + return this._store.add(fragment as FragmentEntry); } - update(fragment) { - this._store.put(fragment); + update(fragment: FragmentEntry): Promise { + return this._store.put(fragment); } - get(roomId, fragmentId) { + get(roomId: string, fragmentId: number): Promise { return this._store.get(encodeKey(roomId, fragmentId)); } - removeAllForRoom(roomId) { - this._store.delete(this._allRange(roomId)); + removeAllForRoom(roomId: string): Promise { + return this._store.delete(this._allRange(roomId)); } } From b46ae152d6d5704e6859e0f58ca53167531ffd13 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Wed, 11 Aug 2021 16:03:42 -0700 Subject: [PATCH 07/15] Migrate PendingEventStore.js to TypeScript --- src/matrix/storage/idb/Transaction.js | 2 +- ...dingEventStore.js => PendingEventStore.ts} | 47 +++++++++++++------ 2 files changed, 33 insertions(+), 16 deletions(-) rename src/matrix/storage/idb/stores/{PendingEventStore.js => PendingEventStore.ts} (60%) diff --git a/src/matrix/storage/idb/Transaction.js b/src/matrix/storage/idb/Transaction.js index 43f26cd2..f66e04dc 100644 --- a/src/matrix/storage/idb/Transaction.js +++ b/src/matrix/storage/idb/Transaction.js @@ -25,7 +25,7 @@ import {TimelineRelationStore} from "./stores/TimelineRelationStore"; import {RoomStateStore} from "./stores/RoomStateStore"; import {RoomMemberStore} from "./stores/RoomMemberStore"; import {TimelineFragmentStore} from "./stores/TimelineFragmentStore"; -import {PendingEventStore} from "./stores/PendingEventStore.js"; +import {PendingEventStore} from "./stores/PendingEventStore"; import {UserIdentityStore} from "./stores/UserIdentityStore.js"; import {DeviceIdentityStore} from "./stores/DeviceIdentityStore.js"; import {OlmSessionStore} from "./stores/OlmSessionStore.js"; diff --git a/src/matrix/storage/idb/stores/PendingEventStore.js b/src/matrix/storage/idb/stores/PendingEventStore.ts similarity index 60% rename from src/matrix/storage/idb/stores/PendingEventStore.js rename to src/matrix/storage/idb/stores/PendingEventStore.ts index 61071f11..6067c3c4 100644 --- a/src/matrix/storage/idb/stores/PendingEventStore.js +++ b/src/matrix/storage/idb/stores/PendingEventStore.ts @@ -16,23 +16,40 @@ limitations under the License. import { encodeUint32, decodeUint32 } from "../utils"; import {KeyLimits} from "../../common"; +import {Store} from "../Store"; +import {Content} from "../../types"; -function encodeKey(roomId, queueIndex) { +interface PendingEntry { + roomId: string; + queueIndex: number; + eventType: string; + content: Content; + relatexTxnId: string | null; + relatedEventId: string | null; + txnId?: string; + needsEncryption: boolean; + needsUpload: boolean; + key: string; +} + +function encodeKey(roomId: string, queueIndex: number): string { return `${roomId}|${encodeUint32(queueIndex)}`; } -function decodeKey(key) { +function decodeKey(key: string): { roomId: string, queueIndex: number } { const [roomId, encodedQueueIndex] = key.split("|"); const queueIndex = decodeUint32(encodedQueueIndex); return {roomId, queueIndex}; } export class PendingEventStore { - constructor(eventStore) { + private _eventStore: Store; + + constructor(eventStore: Store) { this._eventStore = eventStore; } - async getMaxQueueIndex(roomId) { + async getMaxQueueIndex(roomId: string): Promise { const range = this._eventStore.IDBKeyRange.bound( encodeKey(roomId, KeyLimits.minStorageKey), encodeKey(roomId, KeyLimits.maxStorageKey), @@ -41,38 +58,38 @@ export class PendingEventStore { ); const maxKey = await this._eventStore.findMaxKey(range); if (maxKey) { - return decodeKey(maxKey).queueIndex; + return decodeKey(maxKey as string).queueIndex; } } - remove(roomId, queueIndex) { + remove(roomId: string, queueIndex: number): Promise { const keyRange = this._eventStore.IDBKeyRange.only(encodeKey(roomId, queueIndex)); - this._eventStore.delete(keyRange); + return this._eventStore.delete(keyRange); } - async exists(roomId, queueIndex) { + async exists(roomId: string, queueIndex: number): Promise { const keyRange = this._eventStore.IDBKeyRange.only(encodeKey(roomId, queueIndex)); const key = await this._eventStore.getKey(keyRange); return !!key; } - add(pendingEvent) { + add(pendingEvent: PendingEntry): Promise { pendingEvent.key = encodeKey(pendingEvent.roomId, pendingEvent.queueIndex); - this._eventStore.add(pendingEvent); + return this._eventStore.add(pendingEvent); } - update(pendingEvent) { - this._eventStore.put(pendingEvent); + update(pendingEvent: PendingEntry): Promise { + return this._eventStore.put(pendingEvent); } - getAll() { + getAll(): Promise { return this._eventStore.selectAll(); } - removeAllForRoom(roomId) { + removeAllForRoom(roomId: string): Promise { const minKey = encodeKey(roomId, KeyLimits.minStorageKey); const maxKey = encodeKey(roomId, KeyLimits.maxStorageKey); const range = this._eventStore.IDBKeyRange.bound(minKey, maxKey); - this._eventStore.delete(range); + return this._eventStore.delete(range); } } From 8d44df83c42ccf664b26ae63c71d77a29a813293 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Wed, 11 Aug 2021 16:38:37 -0700 Subject: [PATCH 08/15] Migrate UserIdentityStore to TypeScript --- src/matrix/storage/idb/Transaction.js | 2 +- ...rIdentityStore.js => UserIdentityStore.ts} | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) rename src/matrix/storage/idb/stores/{UserIdentityStore.js => UserIdentityStore.ts} (63%) diff --git a/src/matrix/storage/idb/Transaction.js b/src/matrix/storage/idb/Transaction.js index f66e04dc..f1d0eb3b 100644 --- a/src/matrix/storage/idb/Transaction.js +++ b/src/matrix/storage/idb/Transaction.js @@ -26,7 +26,7 @@ import {RoomStateStore} from "./stores/RoomStateStore"; import {RoomMemberStore} from "./stores/RoomMemberStore"; import {TimelineFragmentStore} from "./stores/TimelineFragmentStore"; import {PendingEventStore} from "./stores/PendingEventStore"; -import {UserIdentityStore} from "./stores/UserIdentityStore.js"; +import {UserIdentityStore} from "./stores/UserIdentityStore"; import {DeviceIdentityStore} from "./stores/DeviceIdentityStore.js"; import {OlmSessionStore} from "./stores/OlmSessionStore.js"; import {InboundGroupSessionStore} from "./stores/InboundGroupSessionStore.js"; diff --git a/src/matrix/storage/idb/stores/UserIdentityStore.js b/src/matrix/storage/idb/stores/UserIdentityStore.ts similarity index 63% rename from src/matrix/storage/idb/stores/UserIdentityStore.js rename to src/matrix/storage/idb/stores/UserIdentityStore.ts index 1cf6d636..b84a2709 100644 --- a/src/matrix/storage/idb/stores/UserIdentityStore.js +++ b/src/matrix/storage/idb/stores/UserIdentityStore.ts @@ -13,21 +13,30 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ +import {Store} from "../Store"; + +interface UserIdentity { + userId: string; + roomIds: string[]; + deviceTrackingStatus: number; +} export class UserIdentityStore { - constructor(store) { + private _store: Store; + + constructor(store: Store) { this._store = store; } - get(userId) { + get(userId: string): Promise { return this._store.get(userId); } - set(userIdentity) { - this._store.put(userIdentity); + set(userIdentity: UserIdentity): Promise { + return this._store.put(userIdentity); } - remove(userId) { + remove(userId: string): Promise { return this._store.delete(userId); } } From 3cd0d1f423785a3f01454f570413a85d3adf45a1 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Wed, 11 Aug 2021 16:44:38 -0700 Subject: [PATCH 09/15] Migrate DeviceIdentityStore to TypeScript --- src/matrix/storage/idb/Transaction.js | 2 +- ...dentityStore.js => DeviceIdentityStore.ts} | 43 ++++++++++++------- 2 files changed, 29 insertions(+), 16 deletions(-) rename src/matrix/storage/idb/stores/{DeviceIdentityStore.js => DeviceIdentityStore.ts} (62%) diff --git a/src/matrix/storage/idb/Transaction.js b/src/matrix/storage/idb/Transaction.js index f1d0eb3b..a99dae7a 100644 --- a/src/matrix/storage/idb/Transaction.js +++ b/src/matrix/storage/idb/Transaction.js @@ -27,7 +27,7 @@ import {RoomMemberStore} from "./stores/RoomMemberStore"; import {TimelineFragmentStore} from "./stores/TimelineFragmentStore"; import {PendingEventStore} from "./stores/PendingEventStore"; import {UserIdentityStore} from "./stores/UserIdentityStore"; -import {DeviceIdentityStore} from "./stores/DeviceIdentityStore.js"; +import {DeviceIdentityStore} from "./stores/DeviceIdentityStore"; import {OlmSessionStore} from "./stores/OlmSessionStore.js"; import {InboundGroupSessionStore} from "./stores/InboundGroupSessionStore.js"; import {OutboundGroupSessionStore} from "./stores/OutboundGroupSessionStore"; diff --git a/src/matrix/storage/idb/stores/DeviceIdentityStore.js b/src/matrix/storage/idb/stores/DeviceIdentityStore.ts similarity index 62% rename from src/matrix/storage/idb/stores/DeviceIdentityStore.js rename to src/matrix/storage/idb/stores/DeviceIdentityStore.ts index 207cfb20..b04ce6d7 100644 --- a/src/matrix/storage/idb/stores/DeviceIdentityStore.js +++ b/src/matrix/storage/idb/stores/DeviceIdentityStore.ts @@ -15,33 +15,46 @@ limitations under the License. */ import {MAX_UNICODE, MIN_UNICODE} from "./common"; +import {Store} from "../Store"; -function encodeKey(userId, deviceId) { +interface DeviceIdentity { + userId: string; + deviceId: string; + ed25519Key: string; + curve25519Key: string; + algorithms: string[]; + displayName: string; + key: string; +} + +function encodeKey(userId: string, deviceId: string): string { return `${userId}|${deviceId}`; } -function decodeKey(key) { +function decodeKey(key: string): { userId: string, deviceId: string } { const [userId, deviceId] = key.split("|"); return {userId, deviceId}; } export class DeviceIdentityStore { - constructor(store) { + private _store: Store; + + constructor(store: Store) { this._store = store; } - getAllForUserId(userId) { + getAllForUserId(userId: string): Promise { const range = this._store.IDBKeyRange.lowerBound(encodeKey(userId, "")); return this._store.selectWhile(range, device => { return device.userId === userId; }); } - async getAllDeviceIds(userId) { - const deviceIds = []; + async getAllDeviceIds(userId: string): Promise { + const deviceIds: string[] = []; const range = this._store.IDBKeyRange.lowerBound(encodeKey(userId, "")); await this._store.iterateKeys(range, key => { - const decodedKey = decodeKey(key); + const decodedKey = decodeKey(key as string); // prevent running into the next room if (decodedKey.userId === userId) { deviceIds.push(decodedKey.deviceId); @@ -52,27 +65,27 @@ export class DeviceIdentityStore { return deviceIds; } - get(userId, deviceId) { + get(userId: string, deviceId: string): Promise { return this._store.get(encodeKey(userId, deviceId)); } - set(deviceIdentity) { + set(deviceIdentity: DeviceIdentity): Promise { deviceIdentity.key = encodeKey(deviceIdentity.userId, deviceIdentity.deviceId); - this._store.put(deviceIdentity); + return this._store.put(deviceIdentity); } - getByCurve25519Key(curve25519Key) { + getByCurve25519Key(curve25519Key: string): Promise { return this._store.index("byCurve25519Key").get(curve25519Key); } - remove(userId, deviceId) { - this._store.delete(encodeKey(userId, deviceId)); + remove(userId: string, deviceId: string): Promise { + return this._store.delete(encodeKey(userId, deviceId)); } - removeAllForUser(userId) { + removeAllForUser(userId: string): Promise { // exclude both keys as they are theoretical min and max, // but we should't have a match for just the room id, or room id with max const range = this._store.IDBKeyRange.bound(encodeKey(userId, MIN_UNICODE), encodeKey(userId, MAX_UNICODE), true, true); - this._store.delete(range); + return this._store.delete(range); } } From 914abda7c9362f77e910d3a5ad38bd27b9117cb7 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Thu, 12 Aug 2021 10:19:09 -0700 Subject: [PATCH 10/15] Migrate OlmSessionStore to TypeScript --- src/matrix/storage/idb/Transaction.js | 2 +- ...{OlmSessionStore.js => OlmSessionStore.ts} | 31 +++++++++++++------ 2 files changed, 22 insertions(+), 11 deletions(-) rename src/matrix/storage/idb/stores/{OlmSessionStore.js => OlmSessionStore.ts} (67%) diff --git a/src/matrix/storage/idb/Transaction.js b/src/matrix/storage/idb/Transaction.js index a99dae7a..cc2cde4d 100644 --- a/src/matrix/storage/idb/Transaction.js +++ b/src/matrix/storage/idb/Transaction.js @@ -28,7 +28,7 @@ import {TimelineFragmentStore} from "./stores/TimelineFragmentStore"; import {PendingEventStore} from "./stores/PendingEventStore"; import {UserIdentityStore} from "./stores/UserIdentityStore"; import {DeviceIdentityStore} from "./stores/DeviceIdentityStore"; -import {OlmSessionStore} from "./stores/OlmSessionStore.js"; +import {OlmSessionStore} from "./stores/OlmSessionStore"; import {InboundGroupSessionStore} from "./stores/InboundGroupSessionStore.js"; import {OutboundGroupSessionStore} from "./stores/OutboundGroupSessionStore"; import {GroupSessionDecryptionStore} from "./stores/GroupSessionDecryptionStore"; diff --git a/src/matrix/storage/idb/stores/OlmSessionStore.js b/src/matrix/storage/idb/stores/OlmSessionStore.ts similarity index 67% rename from src/matrix/storage/idb/stores/OlmSessionStore.js rename to src/matrix/storage/idb/stores/OlmSessionStore.ts index d81cc048..a118b963 100644 --- a/src/matrix/storage/idb/stores/OlmSessionStore.js +++ b/src/matrix/storage/idb/stores/OlmSessionStore.ts @@ -13,26 +13,37 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ +import {Store} from "../Store"; -function encodeKey(senderKey, sessionId) { +function encodeKey(senderKey: string, sessionId: string): string { return `${senderKey}|${sessionId}`; } -function decodeKey(key) { +function decodeKey(key: string): { senderKey: string, sessionId: string } { const [senderKey, sessionId] = key.split("|"); return {senderKey, sessionId}; } +interface OlmSession { + session: string; + sessionId: string; + senderKey: string; + lastUsed: number; + key: string; +} + export class OlmSessionStore { - constructor(store) { + private _store: Store; + + constructor(store: Store) { this._store = store; } - async getSessionIds(senderKey) { - const sessionIds = []; + async getSessionIds(senderKey: string): Promise { + const sessionIds: string[] = []; const range = this._store.IDBKeyRange.lowerBound(encodeKey(senderKey, "")); await this._store.iterateKeys(range, key => { - const decodedKey = decodeKey(key); + const decodedKey = decodeKey(key as string); // prevent running into the next room if (decodedKey.senderKey === senderKey) { sessionIds.push(decodedKey.sessionId); @@ -43,23 +54,23 @@ export class OlmSessionStore { return sessionIds; } - getAll(senderKey) { + getAll(senderKey: string): Promise { const range = this._store.IDBKeyRange.lowerBound(encodeKey(senderKey, "")); return this._store.selectWhile(range, session => { return session.senderKey === senderKey; }); } - get(senderKey, sessionId) { + get(senderKey: string, sessionId: string): Promise { return this._store.get(encodeKey(senderKey, sessionId)); } - set(session) { + set(session: OlmSession): Promise { session.key = encodeKey(session.senderKey, session.sessionId); return this._store.put(session); } - remove(senderKey, sessionId) { + remove(senderKey: string, sessionId: string): Promise { return this._store.delete(encodeKey(senderKey, sessionId)); } } From 100aee9dccbd4d55061480162f3dae82e2530b32 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Thu, 12 Aug 2021 10:24:47 -0700 Subject: [PATCH 11/15] Migrate InboundGroupSessionStore to TypeScript --- src/matrix/storage/idb/Transaction.js | 2 +- ...onStore.js => InboundGroupSessionStore.ts} | 29 ++++++++++++++----- 2 files changed, 22 insertions(+), 9 deletions(-) rename src/matrix/storage/idb/stores/{InboundGroupSessionStore.js => InboundGroupSessionStore.ts} (60%) diff --git a/src/matrix/storage/idb/Transaction.js b/src/matrix/storage/idb/Transaction.js index cc2cde4d..8b85b795 100644 --- a/src/matrix/storage/idb/Transaction.js +++ b/src/matrix/storage/idb/Transaction.js @@ -29,7 +29,7 @@ import {PendingEventStore} from "./stores/PendingEventStore"; import {UserIdentityStore} from "./stores/UserIdentityStore"; import {DeviceIdentityStore} from "./stores/DeviceIdentityStore"; import {OlmSessionStore} from "./stores/OlmSessionStore"; -import {InboundGroupSessionStore} from "./stores/InboundGroupSessionStore.js"; +import {InboundGroupSessionStore} from "./stores/InboundGroupSessionStore"; import {OutboundGroupSessionStore} from "./stores/OutboundGroupSessionStore"; import {GroupSessionDecryptionStore} from "./stores/GroupSessionDecryptionStore"; import {OperationStore} from "./stores/OperationStore"; diff --git a/src/matrix/storage/idb/stores/InboundGroupSessionStore.js b/src/matrix/storage/idb/stores/InboundGroupSessionStore.ts similarity index 60% rename from src/matrix/storage/idb/stores/InboundGroupSessionStore.js rename to src/matrix/storage/idb/stores/InboundGroupSessionStore.ts index 488f2510..c1ebfc63 100644 --- a/src/matrix/storage/idb/stores/InboundGroupSessionStore.js +++ b/src/matrix/storage/idb/stores/InboundGroupSessionStore.ts @@ -15,36 +15,49 @@ limitations under the License. */ import {MIN_UNICODE, MAX_UNICODE} from "./common"; +import {Store} from "../Store"; -function encodeKey(roomId, senderKey, sessionId) { +interface InboundGroupSession { + roomId: string; + senderKey: string; + sessionId: string; + session?: string; + claimedKeys?: { [algorithm : string] : string }; + eventIds?: string[]; + key: string; +} + +function encodeKey(roomId: string, senderKey: string, sessionId: string): string { return `${roomId}|${senderKey}|${sessionId}`; } export class InboundGroupSessionStore { - constructor(store) { + private _store: Store; + + constructor(store: Store) { this._store = store; } - async has(roomId, senderKey, sessionId) { + async has(roomId: string, senderKey: string, sessionId: string): Promise { const key = encodeKey(roomId, senderKey, sessionId); const fetchedKey = await this._store.getKey(key); return key === fetchedKey; } - get(roomId, senderKey, sessionId) { + get(roomId: string, senderKey: string, sessionId: string): Promise { return this._store.get(encodeKey(roomId, senderKey, sessionId)); } - set(session) { + set(session: InboundGroupSession): Promise { session.key = encodeKey(session.roomId, session.senderKey, session.sessionId); - this._store.put(session); + return this._store.put(session); } - removeAllForRoom(roomId) { + removeAllForRoom(roomId: string): Promise { const range = this._store.IDBKeyRange.bound( encodeKey(roomId, MIN_UNICODE, MIN_UNICODE), encodeKey(roomId, MAX_UNICODE, MAX_UNICODE) ); - this._store.delete(range); + return this._store.delete(range); } } From bef02d238f9f4526b8ee792d037de270c618fda9 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Tue, 31 Aug 2021 15:12:09 -0700 Subject: [PATCH 12/15] Split keys out of stored data types --- .../idb/stores/GroupSessionDecryptionStore.ts | 13 ++++++------ .../storage/idb/stores/OperationStore.ts | 21 +++++++++++-------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/matrix/storage/idb/stores/GroupSessionDecryptionStore.ts b/src/matrix/storage/idb/stores/GroupSessionDecryptionStore.ts index 2b38c1fb..b6636f13 100644 --- a/src/matrix/storage/idb/stores/GroupSessionDecryptionStore.ts +++ b/src/matrix/storage/idb/stores/GroupSessionDecryptionStore.ts @@ -24,13 +24,14 @@ function encodeKey(roomId: string, sessionId: string, messageIndex: number | str interface GroupSessionDecryption { eventId: string; timestamp: number; - key: string; } -export class GroupSessionDecryptionStore { - private _store: Store; +type GroupSessionEntry = GroupSessionDecryption & { key: string } - constructor(store: Store) { +export class GroupSessionDecryptionStore { + private _store: Store; + + constructor(store: Store) { this._store = store; } @@ -39,8 +40,8 @@ export class GroupSessionDecryptionStore { } set(roomId: string, sessionId: string, messageIndex: number, decryption: GroupSessionDecryption): void { - decryption.key = encodeKey(roomId, sessionId, messageIndex); - this._store.put(decryption); + (decryption as GroupSessionEntry).key = encodeKey(roomId, sessionId, messageIndex); + this._store.put(decryption as GroupSessionEntry); } removeAllForRoom(roomId: string): Promise { diff --git a/src/matrix/storage/idb/stores/OperationStore.ts b/src/matrix/storage/idb/stores/OperationStore.ts index 080d3e66..cccd8e2d 100644 --- a/src/matrix/storage/idb/stores/OperationStore.ts +++ b/src/matrix/storage/idb/stores/OperationStore.ts @@ -20,15 +20,18 @@ export function encodeScopeTypeKey(scope: string, type: string): string { return `${scope}|${type}`; } -interface Operation { +interface BaseOperation { id: string; - type: string; scope: string; userIds: string[]; - scopeTypeKey: string; - roomKeyMessage: RoomKeyMessage; } +type OperationType = { type: "share_room_key"; roomKeyMessage: RoomKeyMessage; } + +type Operation = BaseOperation & OperationType + +type OperationEntry = Operation & { scopeTypeKey: string; } + interface RoomKeyMessage { room_id: string; session_id: string; @@ -38,9 +41,9 @@ interface RoomKeyMessage { } export class OperationStore { - private _store: Store; + private _store: Store; - constructor(store: Store) { + constructor(store: Store) { this._store = store; } @@ -62,12 +65,12 @@ export class OperationStore { } add(operation: Operation): void { - operation.scopeTypeKey = encodeScopeTypeKey(operation.scope, operation.type); - this._store.add(operation); + (operation as OperationEntry).scopeTypeKey = encodeScopeTypeKey(operation.scope, operation.type); + this._store.add(operation as OperationEntry); } update(operation: Operation): void { - this._store.put(operation); + this._store.put(operation as OperationEntry); } remove(id: string): Promise { From f34ee53a1220551ef93b39b916e0b455ae342bf0 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Tue, 31 Aug 2021 15:14:21 -0700 Subject: [PATCH 13/15] Avoid casting to any when a more specific type is possible --- src/matrix/storage/idb/stores/RoomMemberStore.ts | 2 +- src/matrix/storage/idb/stores/TimelineFragmentStore.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/matrix/storage/idb/stores/RoomMemberStore.ts b/src/matrix/storage/idb/stores/RoomMemberStore.ts index e389bb77..00cf607f 100644 --- a/src/matrix/storage/idb/stores/RoomMemberStore.ts +++ b/src/matrix/storage/idb/stores/RoomMemberStore.ts @@ -52,7 +52,7 @@ export class RoomMemberStore { set(member: MemberData): void { // Object.assign would be more typesafe, but small objects - (member as any).key = encodeKey(member.roomId, member.userId); + (member as MemberStorageEntry).key = encodeKey(member.roomId, member.userId); this._roomMembersStore.put(member as MemberStorageEntry); } diff --git a/src/matrix/storage/idb/stores/TimelineFragmentStore.ts b/src/matrix/storage/idb/stores/TimelineFragmentStore.ts index 54b66489..813fc3f3 100644 --- a/src/matrix/storage/idb/stores/TimelineFragmentStore.ts +++ b/src/matrix/storage/idb/stores/TimelineFragmentStore.ts @@ -75,7 +75,7 @@ export class TimelineFragmentStore { // depends if we want to do anything smart with fragment ids, // like give them meaning depending on range. not for now probably ... add(fragment: Fragment): void { - (fragment as any).key = encodeKey(fragment.roomId, fragment.id); + (fragment as FragmentEntry).key = encodeKey(fragment.roomId, fragment.id); this._store.add(fragment as FragmentEntry); } From cd98cac4e4bb0c22b2ba99e16b65f47188e136be Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 6 Sep 2021 12:46:44 +0200 Subject: [PATCH 14/15] split out Entry type for OlmSessionStore --- src/matrix/storage/idb/stores/OlmSessionStore.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/matrix/storage/idb/stores/OlmSessionStore.ts b/src/matrix/storage/idb/stores/OlmSessionStore.ts index eee2074b..1daa0b21 100644 --- a/src/matrix/storage/idb/stores/OlmSessionStore.ts +++ b/src/matrix/storage/idb/stores/OlmSessionStore.ts @@ -29,13 +29,14 @@ interface OlmSession { sessionId: string; senderKey: string; lastUsed: number; - key: string; } -export class OlmSessionStore { - private _store: Store; +type OlmSessionEntry = OlmSession & { key: string }; - constructor(store: Store) { +export class OlmSessionStore { + private _store: Store; + + constructor(store: Store) { this._store = store; } @@ -66,8 +67,8 @@ export class OlmSessionStore { } set(session: OlmSession): void { - session.key = encodeKey(session.senderKey, session.sessionId); - this._store.put(session); + (session as OlmSessionEntry).key = encodeKey(session.senderKey, session.sessionId); + this._store.put(session as OlmSessionEntry); } remove(senderKey: string, sessionId: string): Promise { From ad28f1f9a305c12e8f42095a3f93ca4bedaad59c Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 6 Sep 2021 12:51:28 +0200 Subject: [PATCH 15/15] split out Entry type for TimelineEventStore --- .../storage/idb/stores/TimelineEventStore.ts | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/matrix/storage/idb/stores/TimelineEventStore.ts b/src/matrix/storage/idb/stores/TimelineEventStore.ts index eb4c70cc..f659bdbd 100644 --- a/src/matrix/storage/idb/stores/TimelineEventStore.ts +++ b/src/matrix/storage/idb/stores/TimelineEventStore.ts @@ -27,7 +27,7 @@ interface Annotation { firstTimestamp: number; } -interface StorageEntry { +interface TimelineEventEntry { roomId: string; fragmentId: number; eventIndex: number; @@ -35,10 +35,10 @@ interface StorageEntry { displayName?: string; avatarUrl?: string; annotations?: { [key : string]: Annotation }; - key: string; - eventIdKey: string; } +type TimelineEventStorageEntry = TimelineEventEntry & { key: string, eventIdKey: string }; + function encodeKey(roomId: string, fragmentId: number, eventIndex: number): string { return `${roomId}|${encodeUint32(fragmentId)}|${encodeUint32(eventIndex)}`; } @@ -126,9 +126,9 @@ class Range { * @property {?Gap} gap if a gap entry, the gap */ export class TimelineEventStore { - private _timelineStore: Store; + private _timelineStore: Store; - constructor(timelineStore: Store) { + constructor(timelineStore: Store) { this._timelineStore = timelineStore; } @@ -175,7 +175,7 @@ export class TimelineEventStore { * @param amount * @return a promise resolving to an array with 0 or more entries, in ascending order. */ - async lastEvents(roomId: string, fragmentId: number, amount: number): Promise { + async lastEvents(roomId: string, fragmentId: number, amount: number): Promise { const eventKey = EventKey.maxKey; eventKey.fragmentId = fragmentId; return this.eventsBefore(roomId, eventKey, amount); @@ -187,7 +187,7 @@ export class TimelineEventStore { * @param amount * @return a promise resolving to an array with 0 or more entries, in ascending order. */ - async firstEvents(roomId: string, fragmentId: number, amount: number): Promise { + async firstEvents(roomId: string, fragmentId: number, amount: number): Promise { const eventKey = EventKey.minKey; eventKey.fragmentId = fragmentId; return this.eventsAfter(roomId, eventKey, amount); @@ -200,7 +200,7 @@ export class TimelineEventStore { * @param amount * @return a promise resolving to an array with 0 or more entries, in ascending order. */ - eventsAfter(roomId: string, eventKey: EventKey, amount: number): Promise { + eventsAfter(roomId: string, eventKey: EventKey, amount: number): Promise { const idbRange = this.lowerBoundRange(eventKey, true).asIDBKeyRange(roomId); return this._timelineStore.selectLimit(idbRange, amount); } @@ -212,7 +212,7 @@ export class TimelineEventStore { * @param amount * @return a promise resolving to an array with 0 or more entries, in ascending order. */ - async eventsBefore(roomId: string, eventKey: EventKey, amount: number): Promise { + async eventsBefore(roomId: string, eventKey: EventKey, amount: number): Promise { const range = this.upperBoundRange(eventKey, true).asIDBKeyRange(roomId); const events = await this._timelineStore.selectLimitReverse(range, amount); events.reverse(); // because we fetched them backwards @@ -265,11 +265,11 @@ export class TimelineEventStore { * @return nothing. To wait for the operation to finish, await the transaction it's part of. * @throws {StorageError} ... */ - insert(entry: StorageEntry): void { - entry.key = encodeKey(entry.roomId, entry.fragmentId, entry.eventIndex); - entry.eventIdKey = encodeEventIdKey(entry.roomId, entry.event.event_id); + insert(entry: TimelineEventEntry): void { + (entry as TimelineEventStorageEntry).key = encodeKey(entry.roomId, entry.fragmentId, entry.eventIndex); + (entry as TimelineEventStorageEntry).eventIdKey = encodeEventIdKey(entry.roomId, entry.event.event_id); // TODO: map error? or in idb/store? - this._timelineStore.add(entry); + this._timelineStore.add(entry as TimelineEventStorageEntry); } /** Updates the entry into the store with the given [roomId, eventKey] combination. @@ -277,15 +277,15 @@ export class TimelineEventStore { * @param entry the entry to update. * @return nothing. To wait for the operation to finish, await the transaction it's part of. */ - update(entry: StorageEntry): void { - this._timelineStore.put(entry); + update(entry: TimelineEventEntry): void { + this._timelineStore.put(entry as TimelineEventStorageEntry); } - get(roomId: string, eventKey: EventKey): Promise { + get(roomId: string, eventKey: EventKey): Promise { return this._timelineStore.get(encodeKey(roomId, eventKey.fragmentId, eventKey.eventIndex)); } - getByEventId(roomId: string, eventId: string): Promise { + getByEventId(roomId: string, eventId: string): Promise { return this._timelineStore.index("byEventId").get(encodeEventIdKey(roomId, eventId)); }