import type { IEntry, ListingResult, VALUE_TYPE } from "./types"; // export function listingAsOrdered(listing: ListingResult): OrderedListing { // const entries = Object.entries(listing) as [Address, IEntry][]; // return entries // .sort(([_, a], [__, b]) => // String(a.value.c).localeCompare(String(b.value.c)) // ) // .sort(([_, a], [__, b]) => // String(a.value.t).localeCompare(String(b.value.t)) // ) // .sort(([_, a], [__, b]) => a.attribute.localeCompare(b.attribute)); // } export class UpListing { public readonly entries: UpEntry[]; constructor(listing: ListingResult) { this.entries = Object.entries(listing).map((lr) => new UpEntry(...lr)); } public get objects(): UpObject[] { const allEntities = new Set(this.entries.map((e) => e.entity)); return Array.from(allEntities).map( (entity) => new UpObject(entity, this.entries) ); } } export class UpObject { public readonly address; private entries: UpEntry[]; constructor(address: string, entries?: UpEntry[]) { this.address = address; this.entries = entries || []; } public bind(entries: UpEntry[]) { this.entries = entries; } public bindAppend(entries: UpEntry[]) { this.entries.push(...entries); } public get attributes() { return this.entries.filter((e) => e.entity === this.address); } public get backlinks() { return this.entries.filter((e) => e.value.c === this.address); } public get attr() { const result = {} as { [key: string]: UpEntry[] }; this.attributes.forEach((entry) => { if (!result[entry.attribute]) { result[entry.attribute] = []; } result[entry.attribute].push(entry); }); return result; } public get(attr: string) { return this.attr[attr] ? this.attr[attr][0].value.c : undefined; } public identify(): string[] { // Get all places where this Object is "had" const hasEntries = this.backlinks .filter((entry) => entry.attribute === "HAS") .map((entry) => entry.address); // Out of those relations, retrieve their ALIAS attrs const hasAliases = this.entries .filter( (entry) => entry.attribute === "ALIAS" && hasEntries.includes(entry.entity) ) .map((entry) => String(entry.value.c)); const lblValues = (this.attr["LBL"] || []).map((e) => String(e.value.c)); return lblValues.concat(hasAliases); } public asDict() { return { address: this.address, attributes: this.attr, }; } } export class UpEntry extends UpObject implements IEntry { entity: string; attribute: string; value: { t: VALUE_TYPE; c: string | number }; constructor(address: string, entry: IEntry) { super(address); this.entity = entry.entity; this.attribute = entry.attribute; this.value = entry.value; } }