Migrate StorageFactory to TypeScript

This commit is contained in:
Danila Fedorin 2021-08-13 10:13:40 -07:00
parent 5db9d1493a
commit 9252f3bede
3 changed files with 21 additions and 12 deletions

View file

@ -20,12 +20,16 @@ import { exportSession, importSession } from "./export";
import { schema } from "./schema"; import { schema } from "./schema";
import { detectWebkitEarlyCloseTxnBug } from "./quirks"; import { detectWebkitEarlyCloseTxnBug } from "./quirks";
const sessionName = sessionId => `hydrogen_session_${sessionId}`; const sessionName = (sessionId: string) => `hydrogen_session_${sessionId}`;
const openDatabaseWithSessionId = function(sessionId, idbFactory) { const openDatabaseWithSessionId = function(sessionId: string, idbFactory: IDBFactory): Promise<IDBDatabase> {
return openDatabase(sessionName(sessionId), createStores, schema.length, idbFactory); return openDatabase(sessionName(sessionId), createStores, schema.length, idbFactory);
} }
async function requestPersistedStorage() { interface ServiceWorkerHandler {
preventConcurrentSessionAccess: (sessionId: string) => Promise<void>;
}
async function requestPersistedStorage(): Promise<boolean> {
// don't assume browser so we can run in node with fake-idb // don't assume browser so we can run in node with fake-idb
const glob = this; const glob = this;
if (glob?.navigator?.storage?.persist) { if (glob?.navigator?.storage?.persist) {
@ -43,13 +47,17 @@ async function requestPersistedStorage() {
} }
export class StorageFactory { export class StorageFactory {
constructor(serviceWorkerHandler, idbFactory = window.indexedDB, IDBKeyRange = window.IDBKeyRange) { private _serviceWorkerHandler: ServiceWorkerHandler;
private _idbFactory: IDBFactory;
constructor(serviceWorkerHandler: ServiceWorkerHandler, idbFactory: IDBFactory = window.indexedDB, IDBKeyRange = window.IDBKeyRange) {
this._serviceWorkerHandler = serviceWorkerHandler; this._serviceWorkerHandler = serviceWorkerHandler;
this._idbFactory = idbFactory; this._idbFactory = idbFactory;
// @ts-ignore
this._IDBKeyRange = IDBKeyRange; this._IDBKeyRange = IDBKeyRange;
} }
async create(sessionId) { async create(sessionId: string): Promise<Storage> {
await this._serviceWorkerHandler?.preventConcurrentSessionAccess(sessionId); await this._serviceWorkerHandler?.preventConcurrentSessionAccess(sessionId);
requestPersistedStorage().then(persisted => { requestPersistedStorage().then(persisted => {
// Firefox lies here though, and returns true even if the user denied the request // Firefox lies here though, and returns true even if the user denied the request
@ -60,27 +68,28 @@ export class StorageFactory {
const hasWebkitEarlyCloseTxnBug = await detectWebkitEarlyCloseTxnBug(this._idbFactory); const hasWebkitEarlyCloseTxnBug = await detectWebkitEarlyCloseTxnBug(this._idbFactory);
const db = await openDatabaseWithSessionId(sessionId, this._idbFactory); const db = await openDatabaseWithSessionId(sessionId, this._idbFactory);
// @ts-ignore
return new Storage(db, this._IDBKeyRange, hasWebkitEarlyCloseTxnBug); return new Storage(db, this._IDBKeyRange, hasWebkitEarlyCloseTxnBug);
} }
delete(sessionId) { delete(sessionId: string): Promise<IDBDatabase> {
const databaseName = sessionName(sessionId); const databaseName = sessionName(sessionId);
const req = this._idbFactory.deleteDatabase(databaseName); const req = this._idbFactory.deleteDatabase(databaseName);
return reqAsPromise(req); return reqAsPromise(req);
} }
async export(sessionId) { async export(sessionId: string): Promise<{ [storeName: string]: any }> {
const db = await openDatabaseWithSessionId(sessionId, this._idbFactory); const db = await openDatabaseWithSessionId(sessionId, this._idbFactory);
return await exportSession(db); return await exportSession(db);
} }
async import(sessionId, data) { async import(sessionId: string, data: { [storeName: string]: any }): Promise<void> {
const db = await openDatabaseWithSessionId(sessionId, this._idbFactory); const db = await openDatabaseWithSessionId(sessionId, this._idbFactory);
return await importSession(db, data); return await importSession(db, data);
} }
} }
async function createStores(db, txn, oldVersion, version) { async function createStores(db: IDBDatabase, txn: IDBTransaction, oldVersion: number | null, version: number): Promise<void> {
const startIdx = oldVersion || 0; const startIdx = oldVersion || 0;
for(let i = startIdx; i < version; ++i) { for(let i = startIdx; i < version; ++i) {

View file

@ -15,7 +15,7 @@ limitations under the License.
*/ */
import {FDBFactory, FDBKeyRange} from "../../lib/fake-indexeddb/index.js"; import {FDBFactory, FDBKeyRange} from "../../lib/fake-indexeddb/index.js";
import {StorageFactory} from "../matrix/storage/idb/StorageFactory.js"; import {StorageFactory} from "../matrix/storage/idb/StorageFactory";
export function createMockStorage() { export function createMockStorage() {
return new StorageFactory(null, new FDBFactory(), FDBKeyRange).create(1); return new StorageFactory(null, new FDBFactory(), FDBKeyRange).create(1);

View file

@ -16,7 +16,7 @@ limitations under the License.
import {createFetchRequest} from "./dom/request/fetch.js"; import {createFetchRequest} from "./dom/request/fetch.js";
import {xhrRequest} from "./dom/request/xhr.js"; import {xhrRequest} from "./dom/request/xhr.js";
import {StorageFactory} from "../../matrix/storage/idb/StorageFactory.js"; import {StorageFactory} from "../../matrix/storage/idb/StorageFactory";
import {SessionInfoStorage} from "../../matrix/sessioninfo/localstorage/SessionInfoStorage.js"; import {SessionInfoStorage} from "../../matrix/sessioninfo/localstorage/SessionInfoStorage.js";
import {SettingsStorage} from "./dom/SettingsStorage.js"; import {SettingsStorage} from "./dom/SettingsStorage.js";
import {Encoding} from "./utils/Encoding.js"; import {Encoding} from "./utils/Encoding.js";