Implement Vertex in Post

This commit is contained in:
Chegele 2023-07-06 15:45:21 -04:00
parent 05b0d06aea
commit 07323708b8
1 changed files with 94 additions and 52 deletions

View File

@ -1,5 +1,7 @@
import { Citation } from "./citation";
import { Member } from "./member";
import { Vertex } from "../graph.interface";
import { randomUUID } from "crypto";
export interface AuthorWeight {
weight: number;
@ -11,49 +13,52 @@ export interface CitationWeight {
citation: Citation;
}
export class Post {
export class Post implements Vertex {
private static DEFAULT_WEIGHT = 1000;
private static localStore = new Map<string, Post>;
private title: string;
private content: string;
private authors: AuthorWeight[];
private citations: CitationWeight[];
private authorsWeightTotal: number;
private citationsWeightTotal: number;
public static getAllPosts() {
return Array.from(Post.localStore.values());
}
constructor (title: string, content: string, authors: Member | Member[]) {
this.title = title;
this.content = content;
this.authors = [];
this.citations = [];
this.authorsWeightTotal = 0;
this.citationsWeightTotal = 0;
if (!Array.isArray(authors)) authors = [authors];
for (const author of <Member[]> authors) {
this.authorsWeightTotal += Post.DEFAULT_WEIGHT;
this.authors.push({
weight: Post.DEFAULT_WEIGHT,
author: author
});
}
public static getPost(id: string) {
return Post.localStore.get(id);
}
public static serialize(post: Post, pretty: boolean = true) {
//TODO: Need to convert citations and authors to IDs.
if (!pretty) return JSON.stringify(Post);
return JSON.stringify(Post, undefined, 2);
const postProperties = {
id: post.id,
title: post.title,
content: post.content,
authors: post.authors.map(author => { return {
author: author.id,
weight: post.getWeight(author)
}}),
citations: post.citations.map(citation => { return {
citation: citation.id,
weight: post.getWeight(citation)
}})
}
if (!pretty) return JSON.stringify(postProperties);
return JSON.stringify(postProperties, undefined, 2);
}
public static parse(serializedPost: string) {
//TODO: Need to retrieve citations and authors from IDs.
try {
const parsed = JSON.parse(serializedPost);
const title = <string> parsed?.title;
const content = <string> parsed.content;
const authors = <AuthorWeight[]> parsed.authors;
const citations = <CitationWeight[]> parsed.citations;
const post = new Post(title, content, authors[0].author);
const properties = JSON.parse(serializedPost);
const id = properties.id;
const title = properties.title;
const content = properties.content;
const authors = properties.authors.map(({author, weight}) => {
author = Member.getMember(author) || new Member(author);
return {author, weight};
});
const citations = properties.citations.map(({citation, weight}) => {
citation = Citation.getCitation(citation);
if (citation) return {citation, weight};
});
const post = new Post(id, title, content, authors[0].author);
for (const author of authors) post.setAuthor(author.author, author.weight);
for (const citation of citations) post.setCitation(citation.citation, citation.weight);
return post;
@ -62,47 +67,84 @@ export class Post {
}
}
public getTitle() { return this.title; }
public getContent() { return this.content; }
public getAuthors() { return this.authors.map(({author}) => author); }
public getCitations() { return this.citations.map(({citation}) => citation); }
public getAuthorsWeightTotal() { return this.authorsWeightTotal; }
public getCitationWeightTotal() { return this.citationsWeightTotal; }
private _id: string;
private _title: string;
private _content: string;
private _authors: AuthorWeight[];
private _citations: CitationWeight[];
private _authorsWeightTotal: number;
private _citationsWeightTotal: number;
constructor (id: string | null, title: string, content: string, authors: Member | Member[]) {
this._id = id ? id : randomUUID();
this._title = title;
this._content = content;
this._authors = [];
this._citations = [];
this._authorsWeightTotal = 0;
this._citationsWeightTotal = 0;
if (!Array.isArray(authors)) authors = [authors];
for (const author of <Member[]> authors) {
this._authorsWeightTotal += Post.DEFAULT_WEIGHT;
this._authors.push({
weight: Post.DEFAULT_WEIGHT,
author: author
});
}
Post.localStore.set(this._id, this);
}
public get id() { return this._id; }
public get edges() { return this.citations; }
public get data() { return Post.serialize(this); }
public get title() { return this._title; }
public get content() { return this._content; }
public get authors() { return this._authors.map(({author}) => author); }
public get citations() { return this._citations.map(({citation}) => citation); }
public get authorsWeightTotal() { return this._authorsWeightTotal; }
public get citationsWeightTotal() { return this._citationsWeightTotal; }
public setAuthor(author: Member, weight: number = Post.DEFAULT_WEIGHT) {
this.removeAuthor(author);
this.authors.push({author, weight});
this.authorsWeightTotal += weight;
const index = this.authors.indexOf(author);
if (index != -1) {
const current = this._authors[index];
this._authorsWeightTotal -= current.weight;
this._authors.splice(index, 1);
}
this._authors.push({author, weight});
this._authorsWeightTotal += weight;
}
public removeAuthor(author: Member) {
const index = this.getAuthors().indexOf(author);
if (this.authors.length == 1 ) throw new Error("Cannot remove the last author of a post.");
const index = this.authors.indexOf(author);
if (index != -1) {
const current = this.authors[index];
this.authorsWeightTotal -= current.weight;
this.authors.splice(index, 1);
const current = this._authors[index];
this._authorsWeightTotal -= current.weight;
this._authors.splice(index, 1);
}
}
public setCitation(citation: Citation, weight: number = Post.DEFAULT_WEIGHT) {
this.removeCitation(citation);
this.citations.push({citation, weight});
this.citationsWeightTotal += weight;
this._citations.push({citation, weight});
this._citationsWeightTotal += weight;
}
public removeCitation(citation: Citation) {
const index = this.getCitations().indexOf(citation);
const index = this.citations.indexOf(citation);
if (index != -1) {
const current = this.citations[index];
this.citationsWeightTotal -= current.weight;
this.citations.splice(index, 1);
const current = this._citations[index];
this._citationsWeightTotal -= current.weight;
this._citations.splice(index, 1);
}
}
public getWeight(weighted: Member | Citation) {
const forAuthor = weighted instanceof Member;
const arr = forAuthor ? this.authors : this.citations;
const arr = forAuthor ? this._authors : this._citations;
const key = forAuthor ? "author" : "citation";
const index = arr.findIndex(item => item[key] == weighted);
if (index == -1) return -1;