basic session manager
This commit is contained in:
parent
7601a9b2f8
commit
7a15f12525
6 changed files with 40 additions and 64 deletions
39
src/main.js
39
src/main.js
|
@ -3,22 +3,37 @@ import Session from "./session.js";
|
||||||
import createIdbStorage from "./storage/idb/create.js";
|
import createIdbStorage from "./storage/idb/create.js";
|
||||||
const HOMESERVER = "http://localhost:8008";
|
const HOMESERVER = "http://localhost:8008";
|
||||||
|
|
||||||
async function getLoginData(username, password) {
|
function getSessionId(userId) {
|
||||||
const storedCredentials = localStorage.getItem("morpheus_login");
|
const sessionsJson = localStorage.getItem("morpheus_sessions_v1");
|
||||||
if (!storedCredentials) {
|
if (sessionsJson) {
|
||||||
const api = new Network(HOMESERVER);
|
const sessions = JSON.parse(sessionsJson);
|
||||||
const loginData = await api.passwordLogin(username, password).response();
|
const session = sessions.find(session => session.userId === userId);
|
||||||
localStorage.setItem("morpheus_login", JSON.stringify(loginData));
|
if (session) {
|
||||||
return loginData;
|
return session.id;
|
||||||
} else {
|
}
|
||||||
return JSON.parse(storedCredentials);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function login(username, password, homeserver) {
|
||||||
|
const api = new Network(homeserver);
|
||||||
|
const loginData = await api.passwordLogin(username, password).response();
|
||||||
|
const sessionsJson = localStorage.getItem("morpheus_sessions_v1");
|
||||||
|
const sessions = sessionsJson ? JSON.parse(sessionsJson) : [];
|
||||||
|
const sessionId = (Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)).toString();
|
||||||
|
console.log(loginData);
|
||||||
|
sessions.push({userId: loginData.user_id, id: sessionId});
|
||||||
|
localStorage.setItem("morpheus_sessions_v1", JSON.stringify(sessions));
|
||||||
|
return {sessionId, loginData};
|
||||||
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const loginData = await getLoginData("bruno1", "testtest");
|
let sessionId = getSessionId("@bruno1:localhost");
|
||||||
const network = new Network(HOMESERVER, loginData.access_token);
|
let loginData;
|
||||||
const storage = await createIdbStorage("morpheus_session");
|
if (!sessionId) {
|
||||||
|
({sessionId, loginData} = await login("bruno1", "testtest", "http://localhost:8008"));
|
||||||
|
}
|
||||||
|
const storage = await createIdbStorage(`morpheus_session_${sessionId}`);
|
||||||
|
console.log("database created", storage);
|
||||||
const session = new Session(loginData, storage);
|
const session = new Session(loginData, storage);
|
||||||
await session.load();
|
await session.load();
|
||||||
const sync = new Sync(network, session, storage);
|
const sync = new Sync(network, session, storage);
|
||||||
|
|
|
@ -2,7 +2,7 @@ import Storage from "./storage.js";
|
||||||
import { openDatabase } from "./utils.js";
|
import { openDatabase } from "./utils.js";
|
||||||
|
|
||||||
export default async function createIdbStorage(databaseName) {
|
export default async function createIdbStorage(databaseName) {
|
||||||
const db = await openDatabase(databaseName, createStores);
|
const db = await openDatabase(databaseName, createStores, 1);
|
||||||
return new Storage(db);
|
return new Storage(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export const STORE_NAMES = ["sync", "roomState", "roomSummary", "roomTimeline"];
|
export const STORE_NAMES = ["session", "roomState", "roomSummary", "roomTimeline"];
|
||||||
|
|
||||||
export default class Storage {
|
export default class Storage {
|
||||||
constructor(idbDatabase) {
|
constructor(idbDatabase) {
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
import {openDatabase, select} from "./utils";
|
|
||||||
|
|
||||||
function createSessionsStore(db) {
|
|
||||||
db.createObjectStore("sessions", "id");
|
|
||||||
}
|
|
||||||
|
|
||||||
function createStores(db) {
|
|
||||||
db.createObjectStore("sync"); //sync token
|
|
||||||
db.createObjectStore("roomSummary", "room_id", {unique: true});
|
|
||||||
const timeline = db.createObjectStore("roomTimeline", ["room_id", "sort_key"]);
|
|
||||||
timeline.createIndex("by_event_id", ["room_id", "event.event_id"], {unique: true});
|
|
||||||
// how to get the first/last x events for a room?
|
|
||||||
// we don't want to specify the sort key, but would need an index for the room_id?
|
|
||||||
// take sort_key as primary key then and have index on event_id?
|
|
||||||
// still, you also can't have a PK of [room_id, sort_key] and get the last or first events with just the room_id? the only thing that changes it that the PK will provide an inherent sorting that you inherit in an index that only has room_id as keyPath??? There must be a better way, need to write a prototype test for this.
|
|
||||||
// SOLUTION: with numeric keys, you can just us a min/max value to get first/last
|
|
||||||
// db.createObjectStore("members", ["room_id", "state_key"]);
|
|
||||||
const state = db.createObjectStore("roomState", ["event.room_id", "event.type", "event.state_key"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
class Sessions {
|
|
||||||
|
|
||||||
constructor(databaseName, idToSessionDbName) {
|
|
||||||
this._databaseName = databaseName;
|
|
||||||
this._idToSessionDbName = idToSessionDbName;
|
|
||||||
}
|
|
||||||
|
|
||||||
async getSessions(sessionsDbName) {
|
|
||||||
const db = await openDatabase(this._databaseName, db => createSessionsStore(db));
|
|
||||||
const sessions = await select(db, "sessions");
|
|
||||||
db.close();
|
|
||||||
return sessions;
|
|
||||||
}
|
|
||||||
|
|
||||||
async openSessionStore(session) {
|
|
||||||
const db = await openDatabase(this._idToSessionDbName(session.id), db => createStores(db));
|
|
||||||
return new SessionStore(db);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,14 +7,14 @@ export default class Transaction {
|
||||||
this._txn = txn;
|
this._txn = txn;
|
||||||
this._allowedStoreNames = allowedStoreNames;
|
this._allowedStoreNames = allowedStoreNames;
|
||||||
this._stores = {
|
this._stores = {
|
||||||
sync: null,
|
session: null,
|
||||||
summary: null,
|
roomSummary: null,
|
||||||
timeline: null,
|
roomTimeline: null,
|
||||||
state: null,
|
roomState: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_store(name) {
|
_idbStore(name) {
|
||||||
if (!this._allowedStoreNames.includes(name)) {
|
if (!this._allowedStoreNames.includes(name)) {
|
||||||
// more specific error? this is a bug, so maybe not ...
|
// more specific error? this is a bug, so maybe not ...
|
||||||
throw new Error(`Invalid store for transaction: ${name}, only ${this._allowedStoreNames.join(", ")} are allowed.`);
|
throw new Error(`Invalid store for transaction: ${name}, only ${this._allowedStoreNames.join(", ")} are allowed.`);
|
||||||
|
@ -22,12 +22,12 @@ export default class Transaction {
|
||||||
return new Store(this._txn.getObjectStore(name));
|
return new Store(this._txn.getObjectStore(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
get timeline() {
|
get roomTimeline() {
|
||||||
if (!this._stores.timeline) {
|
if (!this._stores.roomTimeline) {
|
||||||
const idbStore = this._idbStore("timeline");
|
const idbStore = this._idbStore("roomTimeline");
|
||||||
this._stores.timeline = new TimelineStore(idbStore);
|
this._stores.roomTimeline = new TimelineStore(idbStore);
|
||||||
}
|
}
|
||||||
return this._stores.timeline;
|
return this._stores.roomTimeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
complete() {
|
complete() {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export function openDatabase(name, createObjectStore, version = undefined) {
|
export function openDatabase(name, createObjectStore, version) {
|
||||||
const req = window.indexedDB.open(name, version);
|
const req = window.indexedDB.open(name, version);
|
||||||
req.onupgradeneeded = (ev) => {
|
req.onupgradeneeded = (ev) => {
|
||||||
const db = ev.target.result;
|
const db = ev.target.result;
|
||||||
|
|
Reference in a new issue