mirror of
https://github.com/balzack/databag.git
synced 2025-04-23 10:05:19 +00:00
defining store object
This commit is contained in:
parent
f0124247db
commit
11e32e21cf
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "databag-client-sdk",
|
||||
"version": "0.0.18",
|
||||
"version": "0.0.20",
|
||||
"description": "an SDK for developing Databag applications",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.mjs",
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import type { Account, Logging } from './api';
|
||||
import type { AccountStatus } from './types';
|
||||
import { Store } from './store';
|
||||
|
||||
export class AccountModule implements Account {
|
||||
|
||||
@ -9,7 +10,7 @@ export class AccountModule implements Account {
|
||||
private url: string;
|
||||
private log: Logging;
|
||||
|
||||
constructor(log: Logging, token: string, url: string) {
|
||||
constructor(log: Logging, token: string, url: string, store: Store) {
|
||||
this.log = log;
|
||||
this.emitter = new EventEmitter();
|
||||
this.token = token;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import type { Alias, Account, Logging } from './api';
|
||||
import type { Group } from './types';
|
||||
import { Store } from './store';
|
||||
|
||||
export class AliasModule implements Alias {
|
||||
|
||||
@ -10,7 +11,7 @@ export class AliasModule implements Alias {
|
||||
private account: Account;
|
||||
private emitter: EventEmitter;
|
||||
|
||||
constructor(log: Logging, token: string, url: string, account: Account) {
|
||||
constructor(log: Logging, token: string, url: string, account: Account, store: Store) {
|
||||
this.token = token;
|
||||
this.url = url;
|
||||
this.log = log;
|
||||
|
@ -7,8 +7,8 @@
|
||||
import type { Channel, Topic, Asset, Tag, Article, Group, Card, Profile, Call, AccountStatus, NodeConfig, NodeAccount, Repeater } from './types';
|
||||
|
||||
export interface SqlStore {
|
||||
set(stmt: string, params: (string | number)[]): Promise<void>;
|
||||
get(stmt: string, params: (string | number)[]): Promise<any[]>;
|
||||
set(stmt: string, params?: (string | number)[]): Promise<void>;
|
||||
get(stmt: string, params?: (string | number)[]): Promise<any[]>;
|
||||
}
|
||||
|
||||
export interface WebStore {
|
||||
@ -263,9 +263,9 @@ export interface Node {
|
||||
}
|
||||
|
||||
export interface Bot {
|
||||
addTopic(server: string, token: string, type: string, message: string, assets: Asset[]): Promise<string>;
|
||||
removeTopic(server: string, token: string, topicId: string): Promise<void>;
|
||||
addTag(server: string, token: string, topicId: string, type: string, value: string): Promise<string>;
|
||||
removeTag(server: string, token: string, topicId: string, tagId: string): Promise<void>;
|
||||
addTopic(type: string, message: string, assets: Asset[]): Promise<string>;
|
||||
removeTopic(topicId: string): Promise<void>;
|
||||
addTag(topicId: string, type: string, value: string): Promise<string>;
|
||||
removeTag(topicId: string, tagId: string): Promise<void>;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import type { Attribute, Account, Logging } from './api';
|
||||
import type { Article } from './types';
|
||||
import { Store } from './store';
|
||||
|
||||
export class AttributeModule implements Attribute {
|
||||
|
||||
@ -10,7 +11,7 @@ export class AttributeModule implements Attribute {
|
||||
private account: Account;
|
||||
private emitter: EventEmitter;
|
||||
|
||||
constructor(log: Logging, token: string, url: string, account: Account) {
|
||||
constructor(log: Logging, token: string, url: string, account: Account, store: Store) {
|
||||
this.token = token;
|
||||
this.url = url;
|
||||
this.log = log;
|
||||
|
@ -4,22 +4,26 @@ import type { Asset } from './types';
|
||||
export class BotModule implements Bot {
|
||||
|
||||
private log: Logging;
|
||||
private server: string;
|
||||
private token: string;
|
||||
|
||||
constructor(log: Logging) {
|
||||
constructor(log: Logging, server: string, token: string) {
|
||||
this.log = log;
|
||||
this.server = server;
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public async addTopic(server: string, token: string, type: string, message: string, assets: Asset[]): Promise<string> {
|
||||
public async addTopic(type: string, message: string, assets: Asset[]): Promise<string> {
|
||||
return '';
|
||||
}
|
||||
|
||||
public async removeTopic(server: string, token: string, topicId: string): Promise<void> {
|
||||
public async removeTopic(topicId: string): Promise<void> {
|
||||
}
|
||||
|
||||
public async addTag(server: string, token: string, topicId: string, type: string, value: string): Promise<string> {
|
||||
public async addTag(topicId: string, type: string, value: string): Promise<string> {
|
||||
return '';
|
||||
}
|
||||
|
||||
public async removeTag(server: string, token: string, topicId: string, tagId: string): Promise<void> {
|
||||
public async removeTag(topicId: string, tagId: string): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import type { Contact, Logging } from './api';
|
||||
import type { Card, Topic, Asset, Tag, Profile, Repeater} from './types';
|
||||
import { Store } from './store';
|
||||
|
||||
export class ContactModule implements Contact {
|
||||
|
||||
@ -9,7 +10,7 @@ export class ContactModule implements Contact {
|
||||
private url: string;
|
||||
private emitter: EventEmitter;
|
||||
|
||||
constructor(log: Logging, token: string, url: string) {
|
||||
constructor(log: Logging, token: string, url: string, store: Store) {
|
||||
this.token = token;
|
||||
this.url = url;
|
||||
this.log = log;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import type { Content, Account, Logging } from './api';
|
||||
import type { Channel, Topic, Asset, Tag, Repeater } from './types';
|
||||
import { Store } from './store';
|
||||
|
||||
export class ContentModule implements Content {
|
||||
|
||||
@ -10,7 +11,7 @@ export class ContentModule implements Content {
|
||||
private account: Account;
|
||||
private emitter: EventEmitter;
|
||||
|
||||
constructor(log: Logging, token: string, url: string, account: Account) {
|
||||
constructor(log: Logging, token: string, url: string, account: Account, store: Store) {
|
||||
this.token = token;
|
||||
this.url = url;
|
||||
this.log = log;
|
||||
|
@ -186,3 +186,9 @@ export type Revision = {
|
||||
card: number
|
||||
}
|
||||
|
||||
export type Login = {
|
||||
url: string,
|
||||
token: string,
|
||||
timestamp: number,
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import type { Identity, Contact, Content, Focus, Logging } from './api';
|
||||
import type { Topic, Asset, Repeater } from './types';
|
||||
import { Store } from './store';
|
||||
|
||||
export class FocusModule implements Focus {
|
||||
|
||||
@ -12,7 +13,7 @@ export class FocusModule implements Focus {
|
||||
private log: Logging;
|
||||
private emitter: EventEmitter;
|
||||
|
||||
constructor(log: Logging, identity: Identity, contact: Contact, content: Content, cardId: string | null, channelId: string) {
|
||||
constructor(log: Logging, identity: Identity, contact: Contact, content: Content, store: Store, cardId: string | null, channelId: string) {
|
||||
this.identity = identity;
|
||||
this.contact = contact;
|
||||
this.content = content;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import type { Identity, Logging } from './api';
|
||||
import type { Profile } from './types';
|
||||
import { Store } from './store';
|
||||
|
||||
export class IdentityModule implements Identity {
|
||||
|
||||
@ -9,7 +10,7 @@ export class IdentityModule implements Identity {
|
||||
private log: Logging;
|
||||
private emitter: EventEmitter;
|
||||
|
||||
constructor(log: Logging, token: string, url: string) {
|
||||
constructor(log: Logging, token: string, url: string, store: Store) {
|
||||
this.token = token;
|
||||
this.url = url;
|
||||
this.log = log;
|
||||
|
@ -2,6 +2,7 @@ import { SessionModule } from './session';
|
||||
import { NodeModule } from './node';
|
||||
import { BotModule } from './bot';
|
||||
import { ConsoleLogging } from './logging';
|
||||
import { type Store, OfflineStore, OnlineStore, NoStore } from './store';
|
||||
|
||||
import type { Session, Node, Bot, SqlStore, WebStore, Crypto, Logging } from './api';
|
||||
import type { SessionParams } from './types';
|
||||
@ -13,36 +14,43 @@ export class DatabagSDK {
|
||||
|
||||
private log: Logging;
|
||||
private crypto: Crypto | null;
|
||||
private store: SqlStore | WebStore | null = null;
|
||||
private store: Store;
|
||||
|
||||
constructor(crypto: Crypto | null, log: Logging | null) {
|
||||
this.crypto = crypto;
|
||||
this.store = new NoStore();
|
||||
this.log = log ? log : new ConsoleLogging();
|
||||
this.log.info("databag sdk");
|
||||
}
|
||||
|
||||
public async initOfflineStore(sql: SqlStore): Promise<Session | null> {
|
||||
this.store = sql;
|
||||
// initialize
|
||||
return new SessionModule(this.store, this.crypto, this.log, '', '');
|
||||
this.store = new OfflineStore(this.log, sql);
|
||||
const login = await this.store.init();
|
||||
if (!login) {
|
||||
return null;
|
||||
}
|
||||
return new SessionModule(this.store, this.crypto, this.log, login.token, login.url, login.timestamp);
|
||||
}
|
||||
|
||||
public async initOnlineStore(web: WebStore): Promise<Session | null> {
|
||||
this.store = web;
|
||||
// initialize
|
||||
return new SessionModule(this.store, this.crypto, this.log, '', '');
|
||||
this.store = new OnlineStore(this.log, web);
|
||||
const login = await this.store.init();
|
||||
if (!login) {
|
||||
return null;
|
||||
}
|
||||
return new SessionModule(this.store, this.crypto, this.log, login.token, login.url, login.timestamp);
|
||||
}
|
||||
|
||||
public async login(handle: string, password: string, url: string, mfaCode: string | null, params: SessionParams): Promise<Session> {
|
||||
return new SessionModule(this.store, this.crypto, this.log, '', '');
|
||||
return new SessionModule(this.store, this.crypto, this.log, '', '', 0);
|
||||
}
|
||||
|
||||
public async access(url: string, token: string, params: SessionParams): Promise<Session> {
|
||||
return new SessionModule(this.store, this.crypto, this.log, '', '');
|
||||
return new SessionModule(this.store, this.crypto, this.log, '', '', 0);
|
||||
}
|
||||
|
||||
public async create(handle: string, password: string, url: string, token: string | null, params: SessionParams): Promise<Session> {
|
||||
return new SessionModule(this.store, this.crypto, this.log, '', '');
|
||||
return new SessionModule(this.store, this.crypto, this.log, '', '', 0);
|
||||
}
|
||||
|
||||
public async logout(session: Session): Promise<void> {
|
||||
@ -53,7 +61,7 @@ export class DatabagSDK {
|
||||
return new NodeModule(this.log, '', '');
|
||||
}
|
||||
|
||||
public async automate() {
|
||||
return new BotModule(this.log);
|
||||
public async automate(token: string, url: string) {
|
||||
return new BotModule(this.log, token, url);
|
||||
}
|
||||
}
|
||||
|
14
app/sdk/src/logging.ts
Normal file
14
app/sdk/src/logging.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { Logging } from './api';
|
||||
|
||||
export class ConsoleLogging implements Logging {
|
||||
public error(m: any): void {
|
||||
console.log('error:', m);
|
||||
}
|
||||
public warn(m: any): void {
|
||||
console.log('warn:', m);
|
||||
}
|
||||
public info(m: any): void {
|
||||
console.log('info:', m);
|
||||
}
|
||||
}
|
||||
|
@ -12,18 +12,20 @@ import { RingModule } from './ring';
|
||||
|
||||
import { Connection } from './connection';
|
||||
|
||||
import type { Session, SqlStore, WebStore, Account, Identity, Contact, Ring, Alias, Attribute, Content, Stream, Focus, Crypto, Logging } from './api';
|
||||
import type { Session, Account, Identity, Contact, Ring, Alias, Attribute, Content, Stream, Focus, Crypto, Logging } from './api';
|
||||
import { Revision } from './entities';
|
||||
import { Call } from './types';
|
||||
import { Store } from './store';
|
||||
|
||||
export class SessionModule implements Session {
|
||||
|
||||
private emitter: EventEmitter;
|
||||
private store: SqlStore | WebStore | null;
|
||||
private store: Store;
|
||||
private crypto: Crypto | null;
|
||||
private log: Logging;
|
||||
private token: string;
|
||||
private url: string;
|
||||
private loginTimestamp: number;
|
||||
private syncRevision: Revision | null;
|
||||
private status: string;
|
||||
private account: AccountModule;
|
||||
@ -36,24 +38,27 @@ export class SessionModule implements Session {
|
||||
private ring: RingModule;
|
||||
private connection: Connection;
|
||||
|
||||
constructor(store: SqlStore | WebStore | null, crypto: Crypto | null, log: Logging, token: string, url: string) {
|
||||
constructor(store: Store, crypto: Crypto | null, log: Logging, token: string, url: string, loginTimestamp: number) {
|
||||
|
||||
log.info('new databag session');
|
||||
|
||||
this.store = store;
|
||||
this.crypto = crypto;
|
||||
this.log = log;
|
||||
this.token = token;
|
||||
this.url = url;
|
||||
this.loginTimestamp = loginTimestamp;
|
||||
this.syncRevision = null;
|
||||
this.status = 'connecting'
|
||||
this.emitter = new EventEmitter();
|
||||
|
||||
this.account = new AccountModule(log, token, url);
|
||||
this.identity = new IdentityModule(log, token, url);
|
||||
this.contact = new ContactModule(log, token, url);
|
||||
this.alias = new AliasModule(log, token, url, this.account);
|
||||
this.attribute = new AttributeModule(log, token, url, this.account);
|
||||
this.content = new ContentModule(log, token, url, this.account);
|
||||
this.stream = new StreamModule(log, this.contact, this.content);
|
||||
this.account = new AccountModule(log, token, url, this.store);
|
||||
this.identity = new IdentityModule(log, token, url, this.store);
|
||||
this.contact = new ContactModule(log, token, url, this.store);
|
||||
this.alias = new AliasModule(log, token, url, this.account, this.store);
|
||||
this.attribute = new AttributeModule(log, token, url, this.account, this.store);
|
||||
this.content = new ContentModule(log, token, url, this.account, this.store);
|
||||
this.stream = new StreamModule(log, this.contact, this.content, this.store);
|
||||
this.ring = new RingModule(log);
|
||||
this.connection = new Connection(log, token, url);
|
||||
|
||||
@ -168,7 +173,7 @@ export class SessionModule implements Session {
|
||||
}
|
||||
|
||||
public addFocus(cardId: string | null, channelId: string): Focus {
|
||||
return new FocusModule(this.log, this.identity, this.contact, this.content, cardId, channelId);
|
||||
return new FocusModule(this.log, this.identity, this.contact, this.content, this.store, cardId, channelId);
|
||||
}
|
||||
|
||||
public removeFocus(focus: Focus): void {
|
||||
|
64
app/sdk/src/store.ts
Normal file
64
app/sdk/src/store.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import { WebStore, SqlStore, Logging } from './api';
|
||||
import { Login } from './entities';
|
||||
|
||||
export interface Store {
|
||||
init(): Promise<Login | null>;
|
||||
}
|
||||
|
||||
export class OfflineStore implements Store {
|
||||
|
||||
private sql: SqlStore;
|
||||
private log: Logging;
|
||||
|
||||
constructor(log: Logging, sql: SqlStore) {
|
||||
this.sql = sql;
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
private async getAppValue(id: string, unset: any): Promise<any> {
|
||||
const rows = await this.sql.get(`SELECT * FROM app WHERE key='${id}';`);
|
||||
if (rows.length == 1 && rows[0].value != null) {
|
||||
return JSON.parse(rows[0].value);
|
||||
}
|
||||
return unset;
|
||||
}
|
||||
|
||||
public async init(): Promise<Login | null> {
|
||||
await this.sql.set("CREATE TABLE IF NOT EXISTS app (key text, value text, unique(key));");
|
||||
await this.sql.set("INSERT OR IGNORE INTO app (key, value) values ('session', null);");
|
||||
return await this.getAppValue('login', null);
|
||||
}
|
||||
}
|
||||
|
||||
export class OnlineStore implements Store {
|
||||
|
||||
private web: WebStore;
|
||||
private log: Logging;
|
||||
|
||||
constructor(log: Logging, web: WebStore) {
|
||||
this.web = web;
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
private async getAppValue(id: string, unset: any): Promise<any> {
|
||||
const value = await this.web.getValue(id);
|
||||
if (value != null) {
|
||||
return JSON.parse(value);
|
||||
}
|
||||
return unset;
|
||||
}
|
||||
|
||||
public async init(): Promise<Login | null> {
|
||||
return await this.getAppValue('login', null);
|
||||
}
|
||||
}
|
||||
|
||||
export class NoStore implements Store {
|
||||
constructor() {
|
||||
}
|
||||
|
||||
public async init(): Promise<Login | null> {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import type { Contact, Content, Stream, Logging } from './api';
|
||||
import type { Channel } from './types';
|
||||
import { Store } from './store';
|
||||
|
||||
export class StreamModule implements Stream {
|
||||
|
||||
@ -9,7 +10,7 @@ export class StreamModule implements Stream {
|
||||
private content: Content;
|
||||
private emitter: EventEmitter;
|
||||
|
||||
constructor(log: Logging, contact: Contact, content: Content) {
|
||||
constructor(log: Logging, contact: Contact, content: Content, store: Store) {
|
||||
this.contact = contact;
|
||||
this.content = content;
|
||||
this.log = log;
|
||||
|
Loading…
x
Reference in New Issue
Block a user