diff --git a/src/services/reputation/reputation/post.ts b/src/services/reputation/reputation/post.ts index 9c8bc2c..f243aea 100644 --- a/src/services/reputation/reputation/post.ts +++ b/src/services/reputation/reputation/post.ts @@ -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; - 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 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 = parsed?.title; - const content = parsed.content; - const authors = parsed.authors; - const citations = 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 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;