From 646deacb8dee4fd7eb592535cbbe7bed9d971808 Mon Sep 17 00:00:00 2001 From: balzack Date: Mon, 30 Sep 2024 16:45:51 -0700 Subject: [PATCH] defining input/output of contact interface --- app/sdk/src/contact.ts | 120 +++++++++++++++++++++ app/sdk/src/items.ts | 108 +++++++++++++++++++ app/sdk/src/store.ts | 236 +++++++++++++++++++++++++++++++++++++++++ app/sdk/src/types.ts | 7 +- 4 files changed, 466 insertions(+), 5 deletions(-) create mode 100644 app/sdk/src/items.ts diff --git a/app/sdk/src/contact.ts b/app/sdk/src/contact.ts index 02cc5baa..25f87934 100644 --- a/app/sdk/src/contact.ts +++ b/app/sdk/src/contact.ts @@ -1,6 +1,8 @@ import { EventEmitter } from 'eventemitter3'; import type { Contact, Logging } from './api'; import type { Card, Topic, Asset, Tag, Profile, Participant} from './types'; +import type { CardEntity } from './entities'; +import type { ArticleRevision, ArticleDetail, ChannelRevision, ChannelSummary, ChannelDetail, CardRevision, CardNotification, CardProfile, CardDetail } from './items'; import { Store } from './store'; export class ContactModule implements Contact { @@ -12,6 +14,21 @@ export class ContactModule implements Contact { private secure: boolean; private emitter: EventEmitter; + private store: Store; + private revision: number; + private nextRevision: number | null; + private syncing: boolean; + private closing: boolean; + + // view of cards + private cardEntries: Map + + // view of articles + private articleEntries: Map> + + // view of channels + private channelEntries: Map>; + constructor(log: Logging, store: Store, guid: string, token: string, node: string, secure: boolean) { this.guid = guid; this.token = token; @@ -19,16 +36,119 @@ export class ContactModule implements Contact { this.secure = secure; this.log = log; this.emitter = new EventEmitter(); + + this.revision = 0; + this.sycning = true; + this.closing = false; + this.nextRevision = null; + this.init(); + } + + private async init() { + } + + private async sync(): Promise { } public addCardListener(ev: (cards: Card[]) => void): void { this.emitter.on('card', ev); + const cards = Array.from(cardEntries, ([cardId, entry]) => (entry.card)); + ev(cards); } public removeCardListener(ev: (cards: Card[]) => void): void { this.emitter.off('card', ev); } + private emitCards(cards: Card[]) { + this.emitter.emit('card', cards); + } + + public addArticleListener(id: string | null, ev: (arg: { cardId: string, articles: Article[] }) => void): void { + if (id) { + const cardId = id as string; + this.emitter.on(`article::${cardId}`, ev); + const entries = this.articleEntries.get(cardId); + if (entries) { + const articles = Array.from(entries, ([articleId, entry]) => (entry.article)); + ev({ cardId, articles }); + } + } else { + this.emitter.on('article', ev); + this.articleEntries.forEach((entries, cardId) => { + const articles = Array.from(entries, ([articleId, entry]) => (entry.article)); + ev({ cardId, articles }); + }); + } + } + + public removeArticleListener(id: string | null, ev: (arg: { cardId: string, articles: Article[] }) => void): void { + if (id) { + const cardId = id as string; + this.emitter.off(`article::${cardId}`, ev); + } else { + this.emitter.off('article', ev); + } + } + + private emitArticles(cardId: string, articles: Article[]) { + this.emitter.emit('article', { cardId, articles }); + this.emitter.emit(`article::${cardId}`, { cardId, articles }); + } + + public addChannelListener(id: string | null, ev: (arg: { cardId: string, channels: Channel[] }) => void): void { + + if (id) { + const cardId = id as string; + this.emitter.on(`channel::${cardId}`, ev); + const entries = this.channelEntries.get(cardId); + if (entries) { + const channels = Array.from(entries, ([channelId, entry]) => (entry.channel)); + ev({ cardId, channels }); + } + } else { + this.emitter.on('channel', ev); + this.channelEntries.forEach((entries, cardId) => { + const channels = Array.from(entries, ([channelId, entry]) => (entry.channel)); + ev({ cardId, channels }); + }); + } + } + + public removeChannelListener(id: string | null, ev: (arg: { cardId: string, channels: Channel[] }) => void): void { + if (id) { + const cardId = id as string; + this.emitter.off(`channel::${cardId}`, ev); + } else { + this.emitter.off('channel', ev); + } + } + + private emitChannels(cardId: string, channels: Channel[]) { + this.emitter.emit('channel', { cardId, channels }); + this.emitter.emit(`channel::${cardId}`, { cardId, channels }); + } + + public addTopicRevisionListener(cardId: string, channelId: string, ev: (arg: { cardId: string, channelId: string, revision: number }) => void): void { + this.emitter.on(`revision::${cardId}::${channelId}`, ev); + const card = this.channelEntries.get(cardId); + if (card) { + const channel = card.get(channelId); + if (channel) { + const revision = channel.revision.topic; + ev({ cardId, channelId, revision }); + } + } + } + + public removeTopicRevisionListener(cardId: string, channelId: string, ev: (arg: { cardId: string, channelId: string, revision: number }) => void): void { + this.emitter.off(`revision::${cardId}::${channelId}`, ev); + } + + public emitTopicRevision(cardId: string, channelId: string, revision: number) { + this.emitter.emit(`revision::${cardId}::${channelId}`, revision); + } + public async close(): void { } diff --git a/app/sdk/src/items.ts b/app/sdk/src/items.ts new file mode 100644 index 00000000..3a987de5 --- /dev/null +++ b/app/sdk/src/items.ts @@ -0,0 +1,108 @@ +export type CardRevision = { + detail: number, + profile: number, +} + +export type CardNotification = { + profile: number, + article: number, + channel: number, +} + +export type CardDetail = { + status: string, + statusUpdated: number, + token: string, +} + +export type CardProfile = { + handle: string, + guid: string, + name: string, + description: string, + location: string, + imageSet: boolean, + node: string, + seal: string, +} + +export type ChannelRevision = { + topic: number, + detail: number, +} + +export type ChannelSummary = { + guid: string, + dataType: string, + data: string, + created: number, + updated: number, + status: string, + transform: string +} + +export type ChannelDetail = { + revision: number, + dataType: string, + data: string, + created: number, + updated: number, + enableImage: boolean, + enableAudio: boolean, + enableVideo: boolean, + enableBinary: boolean, + contacts: { + groups: [ string ], + cards: [ string ], + }, + members: { + member: string, + pushEnabled: boolean, + }, +} + +export type ArticleRevision = { + detail: number, +} + +export type ArticleDetail = { + dataType: string, + data: string, + created: number, + updated: number, + status: string, + contacts?: { + cards: [ string ], + groups: [ string ], + } +} + +export type CardItem = { + cardId: string, + offsync: boolean, + blocked: boolean, + revision: CardRevision, + profile: CardProfile, + detail: CardDetail, + remote: CardNotification, + sync: CardNotification, +} + +export type ArticleItem = { + cardId: string | null, + articleId: string, + blocked: boolean, + detail: ArticleDetail, + unsealedData: any, + revision: ArticleRevision, +} + +export type ChannelItem = { + cardId: string | null, + channelId: string, + blocked: boolean, + summary: ChannelSummary, + detail: ChannelDetail, + unsealedData: any, + revision: ChannelRevision, +} diff --git a/app/sdk/src/store.ts b/app/sdk/src/store.ts index ad7acc97..0d801b82 100644 --- a/app/sdk/src/store.ts +++ b/app/sdk/src/store.ts @@ -1,4 +1,5 @@ import { Login, ProfileEntity, defaultProfileEntity, ConfigEntity, defaultConfigEntity } from './entities'; +import type { ArticleRevision, ArticleDetail, ArticleItem, ChannelItem, CardItem, CardRevision, CardNotification, CardProfile, CardDetail, ChannelRevision, ChannelSummary, ChannelDetail } from './items'; import type { Logging } from './logging'; export interface Store { @@ -19,6 +20,34 @@ export interface Store { setSettingsRevision(guid: string, revision: number): Promise; getSettingsData(guid: string): Promise; setSettingsData(guid: string, data: ConfigEntity): Promise; + + getContactRevision(guid: string): Promise; + setContactRevision(guid: string, revision: number): Promise; + + getContacts(guid: string): Promise; + setContactCardRevision(guid: string, cardId: string, revision: CardRevision): Promise; + setContactCardProfile(guid: string, cardId: string, profile: CardProfile): Promise; + setContactCardDetail(guid: string, cardId: string, detail: CardDetail): Promise; + setContactCardBlocked(guid: string, cardId: string, blocked: boolean): Promise; + + setContactCardRemoteRevision(guid: string, cardId: string, notification: CardNotification): Promise; + setContactCardSyncRevision(guid: string, cardId: string, notification: CardNotification): Promise; + setContactCardOffsync(guid: string, cardId: string, offsync: boolean): Promise; + + getContactCardArticles(guid: string): Promise; + setContactCardArticleRevision(guid: string, cardId: string, articleId: string, revision: ArticleRevision): Promise; + setContactCardArticleDetail(guid: string, cardId: string, articleId: string, detail: ChannelDetail, unsealedData: any): Promise; + setContactCardArticleUnsealed(guid: string, cardId: string, articleId: string, unsealedData: any): Promise; + + getContactCardChannels(guid: string): Promise; + setContactCardChannelBlocked(guid: string, cardId: string, channelId: string, blocked: boolean): Promise; + setContactCardChannelRevision(guid: string, cardId: string, channelId: string, revision: ChannelRevision): Promise; + setContactCardChannelSummary(guid: string, cardId: string, channelId: string, summary: ChannelSummary): Promise; + setContactCardChannelDetail(guid: string, cardId: string, channelId: string, detail: ChannelDetail, unsealedData: any): Promise; + setContactCardChannelUnsealed(guid: string, cardId: string, channelId: string, unsealedData: any): Promise; + + setContactCardChannelTopicSyncRevision(guid: string, cardId: string, channelId: string, revision: number): Promise; + setContactCardChannelTopicRemoteRevision(guid: string, cardId: string, channelId: string, revision: number): Promise; } export interface SqlStore { @@ -130,6 +159,75 @@ export class OfflineStore implements Store { await this.setAppValue(guid, 'account_data', data); } + public async getContactRevision(guid: string): Promise { + return 0; + } + + public async setContactRevision(guid: string, revision: number): Promise { + } + + public async getContacts(guid: string): Promise { + return []; + } + + public async setContactCardRevision(guid: string, cardId: string, revision: CardRevision): Promise { + } + + public async setContactCardProfile(guid: string, cardId: string, profile: CardProfile): Promise { + } + + public async setContactCardDetail(guid: string, cardId: string, detail: CardDetail): Promise { + } + + public async setContactCardBlocked(guid: string, cardId: string, blocked: boolean): Promise { + } + + public async setContactCardRemoteRevision(guid: string, cardId: string, notification: CardNotification): Promise { + } + + public async setContactCardSyncRevision(guid: string, cardId: string, notification: CardNotification): Promise { + } + + public async setContactCardOffsync(guid: string, cardId: string, offsync: boolean): Promise { + } + + public async getContactCardArticles(guid: string): Promise { + return []; + } + + public async setContactCardArticleRevision(guid: string, cardId: string, articleId: string, revision: ArticleRevision): Promise { + } + + public async setContactCardArticleDetail(guid: string, cardId: string, articleId: string, detail: ChannelDetail, unsealedData: any): Promise { + } + + public async setContactCardArticleUnsealed(guid: string, cardId: string, articleId: string, unsealedData: any): Promise { + } + + public async getContactCardChannels(guid: string): Promise { + return []; + } + + public async setContactCardChannelBlocked(guid: string, cardId: string, channelId: string, blocked: boolean): Promise { + } + + public async setContactCardChannelRevision(guid: string, cardId: string, channelId: string, revision: ChannelRevision): Promise { + } + + public async setContactCardChannelSummary(guid: string, cardId: string, channelId: string, summary: ChannelSummary): Promise { + } + + public async setContactCardChannelDetail(guid: string, cardId: string, channelId: string, detail: ChannelDetail, unsealedData: any): Promise { + } + + public async setContactCardChannelUnsealed(guid: string, cardId: string, channelId: string, unsealedData: any): Promise { + } + + public async setContactCardChannelTopicSyncRevision(guid: string, cardId: string, channelId: string, revision: number): Promise { + } + + public async setContactCardChannelTopicRemoteRevision(guid: string, cardId: string, channelId: string, revision: number): Promise { + } } export class OnlineStore implements Store { @@ -210,6 +308,75 @@ export class OnlineStore implements Store { public async setSettingsData(guid: string, data: ConfigEntity): Promise { } + public async getContactRevision(guid: string): Promise { + return 0; + } + + public async setContactRevision(guid: string, revision: number): Promise { + } + + public async getContacts(guid: string): Promise { + return []; + } + + public async setContactCardRevision(guid: string, cardId: string, revision: CardRevision): Promise { + } + + public async setContactCardProfile(guid: string, cardId: string, profile: CardProfile): Promise { + } + + public async setContactCardDetail(guid: string, cardId: string, detail: CardDetail): Promise { + } + + public async setContactCardBlocked(guid: string, cardId: string, blocked: boolean): Promise { + } + + public async setContactCardRemoteRevision(guid: string, cardId: string, notification: CardNotification): Promise { + } + + public async setContactCardSyncRevision(guid: string, cardId: string, notification: CardNotification): Promise { + } + + public async setContactCardOffsync(guid: string, cardId: string, offsync: boolean): Promise { + } + + public async getContactCardArticles(guid: string): Promise { + return []; + } + + public async setContactCardArticleRevision(guid: string, cardId: string, articleId: string, revision: ArticleRevision): Promise { + } + + public async setContactCardArticleDetail(guid: string, cardId: string, articleId: string, detail: ChannelDetail, unsealedData: any): Promise { + } + + public async setContactCardArticleUnsealed(guid: string, cardId: string, articleId: string, unsealedData: any): Promise { + } + + public async getContactCardChannels(guid: string): Promise { + return []; + } + + public async setContactCardChannelBlocked(guid: string, cardId: string, channelId: string, blocked: boolean): Promise { + } + + public async setContactCardChannelRevision(guid: string, cardId: string, channelId: string, revision: ChannelRevision): Promise { + } + + public async setContactCardChannelSummary(guid: string, cardId: string, channelId: string, summary: ChannelSummary): Promise { + } + + public async setContactCardChannelDetail(guid: string, cardId: string, channelId: string, detail: ChannelDetail, unsealedData: any): Promise { + } + + public async setContactCardChannelUnsealed(guid: string, cardId: string, channelId: string, unsealedData: any): Promise { + } + + public async setContactCardChannelTopicSyncRevision(guid: string, cardId: string, channelId: string, revision: number): Promise { + } + + public async setContactCardChannelTopicRemoteRevision(guid: string, cardId: string, channelId: string, revision: number): Promise { + } } export class NoStore implements Store { @@ -264,5 +431,74 @@ export class NoStore implements Store { public async setSettingsData(guid: string, data: ConfigEntity): Promise { } + public async getContactRevision(guid: string): Promise { + return 0; + } + + public async setContactRevision(guid: string, revision: number): Promise { + } + + public async getContacts(guid: string): Promise { + return []; + } + + public async setContactCardRevision(guid: string, cardId: string, revision: CardRevision): Promise { + } + + public async setContactCardProfile(guid: string, cardId: string, profile: CardProfile): Promise { + } + + public async setContactCardDetail(guid: string, cardId: string, detail: CardDetail): Promise { + } + + public async setContactCardBlocked(guid: string, cardId: string, blocked: boolean): Promise { + } + + public async setContactCardRemoteRevision(guid: string, cardId: string, notification: CardNotification): Promise { + } + + public async setContactCardSyncRevision(guid: string, cardId: string, notification: CardNotification): Promise { + } + + public async setContactCardOffsync(guid: string, cardId: string, offsync: boolean): Promise { + } + + public async getContactCardArticles(guid: string): Promise { + return []; + } + + public async setContactCardArticleRevision(guid: string, cardId: string, articleId: string, revision: ArticleRevision): Promise { + } + + public async setContactCardArticleDetail(guid: string, cardId: string, articleId: string, detail: ChannelDetail, unsealedData: any): Promise { + } + + public async setContactCardArticleUnsealed(guid: string, cardId: string, articleId: string, unsealedData: any): Promise { + } + + public async getContactCardChannels(guid: string): Promise { + return []; + } + + public async setContactCardChannelBlocked(guid: string, cardId: string, channelId: string, blocked: boolean): Promise { + } + + public async setContactCardChannelRevision(guid: string, cardId: string, channelId: string, revision: ChannelRevision): Promise { + } + + public async setContactCardChannelSummary(guid: string, cardId: string, channelId: string, summary: ChannelSummary): Promise { + } + + public async setContactCardChannelDetail(guid: string, cardId: string, channelId: string, detail: ChannelDetail, unsealedData: any): Promise { + } + + public async setContactCardChannelUnsealed(guid: string, cardId: string, channelId: string, unsealedData: any): Promise { + } + + public async setContactCardChannelTopicSyncRevision(guid: string, cardId: string, channelId: string, revision: number): Promise { + } + + public async setContactCardChannelTopicRemoteRevision(guid: string, cardId: string, channelId: string, revision: number): Promise { + } } diff --git a/app/sdk/src/types.ts b/app/sdk/src/types.ts index bb5f08df..e40fabe5 100644 --- a/app/sdk/src/types.ts +++ b/app/sdk/src/types.ts @@ -2,7 +2,6 @@ export type Card = { id: string, status: string, statusUpdated: number, - groups: string[], guid: string, handle: string, name: string, @@ -11,8 +10,6 @@ export type Card = { imageSet: boolean, version: string, node: string, - articles: Article[], - channels: Channel[], } export type Call = { @@ -52,7 +49,7 @@ export type Channel = { sealed: boolean, unsealed: boolean; dataType: string, - data: string, + data: any, created: number, updated: number, enableImage: boolean, @@ -90,7 +87,7 @@ export type Topic = { sealed: boolean, unsealed: boolean, dataType: string, - data: string, + data: any, created: number, updated: number, status: string,