forked from mystiq/hydrogen-web
basic session loading
This commit is contained in:
parent
c115164822
commit
3f776129f5
10 changed files with 94 additions and 101 deletions
10
src/main.js
10
src/main.js
|
@ -30,12 +30,18 @@ async function main() {
|
|||
let sessionId = getSessionId("@bruno1:localhost");
|
||||
let loginData;
|
||||
if (!sessionId) {
|
||||
({sessionId, loginData} = await login("bruno1", "testtest", "http://localhost:8008"));
|
||||
({sessionId, loginData} = await login("bruno1", "testtest", HOMESERVER));
|
||||
}
|
||||
const storage = await createIdbStorage(`morpheus_session_${sessionId}`);
|
||||
console.log("database created", storage);
|
||||
const session = new Session(loginData, storage);
|
||||
const session = new Session(storage);
|
||||
if (loginData) {
|
||||
await session.setLoginData(loginData);
|
||||
}
|
||||
await session.load();
|
||||
console.log("session loaded", session);
|
||||
return;
|
||||
const network = new Network(HOMESERVER, session.accessToken);
|
||||
const sync = new Sync(network, session, storage);
|
||||
await sync.start();
|
||||
|
||||
|
|
|
@ -1,14 +1,25 @@
|
|||
export default class Session {
|
||||
// sessionData has device_id, user_id, home_server (not access_token, that is for network)
|
||||
constructor(sessionData, storage) {
|
||||
this._sessionData = sessionData;
|
||||
// loginData has device_id, user_id, home_server, access_token
|
||||
constructor(storage) {
|
||||
this._storage = storage;
|
||||
this._rooms = {};
|
||||
this._syncToken = null;
|
||||
this._session = null;
|
||||
this._rooms = null;
|
||||
}
|
||||
// should be called before load
|
||||
async setLoginData(loginData) {
|
||||
const txn = this._storage.readWriteTxn([this._storage.storeNames.session]);
|
||||
const session = {loginData};
|
||||
txn.session.set(session);
|
||||
await txn.complete();
|
||||
}
|
||||
|
||||
load() {
|
||||
// what is the PK for a session [user_id, device_id], a uuid?
|
||||
async load() {
|
||||
const txn = this._storage.readTxn([this._storage.storeNames.session]);
|
||||
this._session = await txn.session.get();
|
||||
if (!this._session) {
|
||||
throw new Error("session store is empty");
|
||||
}
|
||||
// load rooms
|
||||
}
|
||||
|
||||
getRoom(roomId) {
|
||||
|
@ -22,7 +33,15 @@ export default class Session {
|
|||
}
|
||||
|
||||
applySync(syncToken, accountData, txn) {
|
||||
this._syncToken = syncToken;
|
||||
txn.session.setSyncToken(syncToken);
|
||||
this._session.syncToken = syncToken;
|
||||
txn.session.setSession(this._session);
|
||||
}
|
||||
|
||||
get syncToken() {
|
||||
return this._session.syncToken;
|
||||
}
|
||||
|
||||
get accessToken() {
|
||||
return this._session.loginData.access_token;
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ export default async function createIdbStorage(databaseName) {
|
|||
}
|
||||
|
||||
function createStores(db) {
|
||||
db.createObjectStore("sync"); //sync token
|
||||
db.createObjectStore("session", {keyPath: "key"});
|
||||
// any way to make keys unique here?
|
||||
db.createObjectStore("roomSummary", {keyPath: "room_id"});
|
||||
const timeline = db.createObjectStore("roomTimeline", {keyPath: ["room_id", "sort_key"]});
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import {iterateCursor} from "./utils";
|
||||
import {iterateCursor} from "./utils.js";
|
||||
|
||||
export default class QueryTarget {
|
||||
constructor(target) {
|
||||
this._target = target;
|
||||
}
|
||||
|
||||
reduce(range, reducer, initialValue) {
|
||||
return this._reduce(range, reducer, initialValue, "next");
|
||||
}
|
||||
|
@ -26,7 +30,7 @@ export default class QueryTarget {
|
|||
}
|
||||
|
||||
selectAll(range) {
|
||||
const cursor = this._queryTarget().openCursor(range, direction);
|
||||
const cursor = this._target.openCursor(range, direction);
|
||||
const results = [];
|
||||
return iterateCursor(cursor, (value) => {
|
||||
results.push(value);
|
||||
|
@ -52,7 +56,7 @@ export default class QueryTarget {
|
|||
|
||||
_reduce(range, reducer, initialValue, direction) {
|
||||
let reducedValue = initialValue;
|
||||
const cursor = this._queryTarget().openCursor(range, direction);
|
||||
const cursor = this._target.openCursor(range, direction);
|
||||
return iterateCursor(cursor, (value) => {
|
||||
reducedValue = reducer(reducedValue, value);
|
||||
return true;
|
||||
|
@ -66,7 +70,7 @@ export default class QueryTarget {
|
|||
}
|
||||
|
||||
_selectWhile(range, predicate, direction) {
|
||||
const cursor = this._queryTarget().openCursor(range, direction);
|
||||
const cursor = this._target.openCursor(range, direction);
|
||||
const results = [];
|
||||
return iterateCursor(cursor, (value) => {
|
||||
results.push(value);
|
||||
|
@ -75,20 +79,17 @@ export default class QueryTarget {
|
|||
}
|
||||
|
||||
async _find(range, predicate, direction) {
|
||||
const cursor = this._queryTarget().openCursor(range, direction);
|
||||
const cursor = this._target.openCursor(range, direction);
|
||||
let result;
|
||||
const found = await iterateCursor(cursor, (value) => {
|
||||
if (predicate(value)) {
|
||||
const found = predicate(value);
|
||||
if (found) {
|
||||
result = value;
|
||||
}
|
||||
return found;
|
||||
});
|
||||
if (!found) {
|
||||
throw new Error("not found");
|
||||
if (found) {
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
_queryTarget() {
|
||||
throw new Error("override this");
|
||||
}
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
import Transaction from "./transaction.js";
|
||||
|
||||
export const STORE_NAMES = ["session", "roomState", "roomSummary", "roomTimeline"];
|
||||
|
||||
export default class Storage {
|
||||
|
@ -17,13 +19,13 @@ export default class Storage {
|
|||
}
|
||||
}
|
||||
|
||||
startReadOnlyTxn(storeNames) {
|
||||
readTxn(storeNames) {
|
||||
this._validateStoreNames(storeNames);
|
||||
const txn = this._db.transaction(storeNames, "readonly");
|
||||
return new Transaction(txn, storeNames);
|
||||
}
|
||||
|
||||
startReadWriteTxn(storeNames) {
|
||||
readWriteTxn(storeNames) {
|
||||
this._validateStoreNames(storeNames);
|
||||
const txn = this._db.transaction(storeNames, "readwrite");
|
||||
return new Transaction(txn, storeNames);
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
import QueryTarget from "./query-target.js";
|
||||
|
||||
export default class StoreIndex extends QueryTarget {
|
||||
constructor(index) {
|
||||
this._index = index;
|
||||
}
|
||||
|
||||
_queryTarget() {
|
||||
return this._index;
|
||||
}
|
||||
}
|
|
@ -1,16 +1,24 @@
|
|||
import QueryTarget from "./query-target.js";
|
||||
import StoreIndex from "./store-index.js";
|
||||
import { reqAsPromise } from "./utils.js";
|
||||
|
||||
export default class Store extends QueryTarget {
|
||||
constructor(store) {
|
||||
this._store = store;
|
||||
super(store);
|
||||
}
|
||||
|
||||
_queryTarget() {
|
||||
return this._store;
|
||||
get _store() {
|
||||
return this._target;
|
||||
}
|
||||
|
||||
index(indexName) {
|
||||
return new StoreIndex(this._store.index(indexName));
|
||||
return new QueryTarget(this._store.index(indexName));
|
||||
}
|
||||
|
||||
put(value) {
|
||||
return reqAsPromise(this._store.put(value));
|
||||
}
|
||||
|
||||
add(value) {
|
||||
return reqAsPromise(this._store.add(value));
|
||||
}
|
||||
}
|
|
@ -14,59 +14,19 @@ store contains:
|
|||
avatarUrl
|
||||
lastSynced
|
||||
*/
|
||||
class SessionStore {
|
||||
|
||||
export default class SessionStore {
|
||||
constructor(sessionStore) {
|
||||
this._sessionStore = sessionStore;
|
||||
}
|
||||
|
||||
readSession() {
|
||||
return this._session;
|
||||
async get() {
|
||||
const session = await this._sessionStore.selectFirst(IDBKeyRange.only(1));
|
||||
if (session) {
|
||||
return session.value;
|
||||
}
|
||||
}
|
||||
|
||||
writeSession(session) {
|
||||
|
||||
}
|
||||
|
||||
// or dedicated set sync_token method?
|
||||
async setAvatar(avatar) {
|
||||
|
||||
}
|
||||
|
||||
async setDisplayName(displayName) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
getSyncStatus() {
|
||||
return this._db.store("sync").selectFirst();
|
||||
}
|
||||
|
||||
setSyncStatus(syncToken, lastSynced) {
|
||||
return this._db.store("sync").updateFirst({sync_token: syncToken, last_synced: lastSynced});
|
||||
// return updateSingletonStore(this._db, "sync", {sync_token: syncToken, last_synced: lastSynced});
|
||||
}
|
||||
|
||||
setAccessToken(accessToken) {
|
||||
}
|
||||
|
||||
async addRoom(room) {
|
||||
|
||||
}
|
||||
|
||||
async removeRoom(roomId) {
|
||||
|
||||
}
|
||||
|
||||
async getRoomStores() {
|
||||
|
||||
}
|
||||
|
||||
async getRoomStore(roomId) {
|
||||
|
||||
}
|
||||
|
||||
async startSyncTransaction() {
|
||||
return this._db.startSyncTxn();
|
||||
set(session) {
|
||||
return this._sessionStore.put({key: 1, value: session});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import GapSortKey from "./gapsortkey";
|
||||
import {select} from "./utils";
|
||||
import SortKey from "../../sortkey.js";
|
||||
|
||||
class TimelineStore {
|
||||
constructor(timelineStore) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import {txnAsPromise} from "./utils";
|
||||
import {txnAsPromise} from "./utils.js";
|
||||
import Store from "./store.js";
|
||||
import TimelineStore from "./stores/timeline.js";
|
||||
// import TimelineStore from "./stores/timeline.js";
|
||||
import SessionStore from "./stores/session.js";
|
||||
|
||||
export default class Transaction {
|
||||
constructor(txn, allowedStoreNames) {
|
||||
|
@ -19,15 +20,23 @@ export default class Transaction {
|
|||
// more specific error? this is a bug, so maybe not ...
|
||||
throw new Error(`Invalid store for transaction: ${name}, only ${this._allowedStoreNames.join(", ")} are allowed.`);
|
||||
}
|
||||
return new Store(this._txn.getObjectStore(name));
|
||||
return new Store(this._txn.objectStore(name));
|
||||
}
|
||||
|
||||
get roomTimeline() {
|
||||
if (!this._stores.roomTimeline) {
|
||||
const idbStore = this._idbStore("roomTimeline");
|
||||
this._stores.roomTimeline = new TimelineStore(idbStore);
|
||||
_store(name, mapStore) {
|
||||
if (!this._stores[name]) {
|
||||
const idbStore = this._idbStore(name);
|
||||
this._stores[name] = mapStore(idbStore);
|
||||
}
|
||||
return this._stores.roomTimeline;
|
||||
return this._stores[name];
|
||||
}
|
||||
|
||||
// get roomTimeline() {
|
||||
// return this._store("roomTimeline", idbStore => new TimelineStore(idbStore));
|
||||
// }
|
||||
|
||||
get session() {
|
||||
return this._store("session", idbStore => new SessionStore(idbStore));
|
||||
}
|
||||
|
||||
complete() {
|
||||
|
|
Loading…
Reference in a new issue