+ New cache ipc handlers for adding server caches

Interface for this is fiddly and probably requires real docs to be further developed
without losing my mind doc the whole cache at some point
+ New cache ipc handlers for adding a new open web socket
Web socket comes with some basic listeners, however very litte/nothing
is being done check the health of these connections or to try when possible.

+ Cache now adds actual message objects to its message arrays instead of raw strings (wew)
+ Events module has been added to move the parsing logic/validation away from everything else

+ The basic Event structure has some niftier-than-you-think behavior for data acccess which the cache can leverage for more concise+ correct behavior
This commit is contained in:
shockrah
2021-04-14 22:51:35 -07:00
parent 01c245cbba
commit 40351f934e
3 changed files with 158 additions and 17 deletions

View File

@@ -1,14 +1,18 @@
import * as EventEmitter from 'events'; // unused for now but maybe useful later
import { ServerConfig, Message, Channel } from './types';
import { Event } from './events';
class ServerCache {
channels: Array<Channel>
// Channel id's are used to key into the list of messages for that given channel
messages: Map<Number, Array<Message>>
// Channel-id => Array<Message>
messages: Map<BigInt, Array<Message>>
config: ServerConfig
constructor(config: ServerConfig, channels: Array<Channel>, messages: Array<Message>) {
this.config = config
this.channels = channels
this.messages = new Map()
for(const message of messages) {
const ref = this.messages.get(message.cid)
@@ -18,45 +22,45 @@ class ServerCache {
ref.push(message)
}
}
console.log('initial message cache: ', this.messages)
}
push_message(message: Message) {
let ref = this.messages.get(message.cid)
if(ref) {
ref.push(message)
ref.push(message) // NOTE: this one here?
console.log('pushed')
} else {
this.messages.set(message.cid, [message])
console.log('set')
}
console.log('message cache state: ', this.messages.get(message.cid))
console.log('message: ', message)
}
}
export class Cache {
export class Cache extends EventEmitter {
// hostname -> Cache
servers: Map<String, ServerCache>
private servers: Map<String, ServerCache>
public active_host: String
constructor() {
super()
this.servers = new Map()
this.active_host = null
}
add_server(hostname: String, servercfg: ServerConfig, channels: Array<Channel>, messages: Array<Message>) {
add_server(url: String, servercfg: ServerConfig, channels: Array<Channel>, messages: Array<Message>) {
let new_entry = new ServerCache(servercfg, channels, messages)
this.servers.set(servercfg.url, new_entry)
}
add_message(hostname: String, message: Message) {
let ref = this.servers.get(hostname)
if(!ref) {
throw `No server config found for ${hostname}`
}
ref.push_message(message)
this.servers.set(url, new_entry)
console.log(this.servers)
}
update_channels(hostname: String, channels: Array<Channel>) {
this.servers.get(hostname).channels = channels
}
last_id(hostname: String, channel_id: Number) : Number|null {
last_id(hostname: String, channel_id: BigInt) : BigInt|null {
try {
let ref = this.servers.get(hostname).messages.get(channel_id)
return ref[ref.length - 1].cid
@@ -64,5 +68,24 @@ export class Cache {
return null
}
}
new_message(origin: String, message: string): void {
// we assume at this point that we have the hostname contained smoewhere
let ref = this.servers.get(origin)
if(ref) {
let event = new Event(message)
ref.push_message(event.message)
} else {
console.error(`No server with ${origin} as hostname`)
console.error('Active host: ', this.active_host)
console.error('Servers: ', this.servers)
}
}
set_active(url: String) {
this.active_host = url
}
}

View File

@@ -0,0 +1,63 @@
import * as JSONBig from 'json-bigint';
import { Channel, Message } from './types';
export class Event {
public type: string
public message: Message|null
// NOTE: these two fields may benefit from have a more legible property wrapping
// them, cost would be pretty minimal(probably but idrk)
public d_channel: Channel|null
public c_channel: Channel|null
constructor(raw: string) {
const parsed = JSONBig.parse(raw)
this.type = parsed['type']
switch(this.type) {
case 'new-message' : {
this.message = this._message(parsed[this.type])
this.d_channel = null
this.c_channel = null
break
}
case 'delete-channel' : {
this.d_channel = null
// todo
break
}
case 'create-channel' : {
this.c_channel = null
// todo
break
}
default: {
this.message = null
this.d_channel = null
this.c_channel = null
}
}
}
// Attempts to setup a new Message object in the message field
private _message(obj: Object): Message|null {
// NOTE: this takes data from the network directly so its important
// to keep in mind the "user-friendly" field names
let uid = obj['author_id']
let cid = obj['channel_id']
let content = obj['content']
let content_type = obj['content_type']
let mid = obj['id']
let uname = obj['name']
let time = obj['time']
return new Message(mid, time, content, content_type, uid, uname, cid)
}
// Sets up the inner channel data
private _channel(obj: Object) : Channel|null {
// todo: still require some testing to verify event data is appropriate
return null
}
}