import type { IEntry, IValue, ListingResult } from "./types"; export { UpEndApi } from "./api"; export { Query } from "./query"; export class UpListing { public readonly entries: UpEntry[]; private _objects: { [key: string]: UpObject } = {}; constructor(listing: ListingResult) { this.entries = Object.entries(listing).map( (lr) => new UpEntry(...lr, this), ); } public get objects() { const allEntities = new Set(this.entries.map((e) => e.entity)); const result: { [key: string]: UpObject } = {}; Array.from(allEntities).forEach( (entity) => (result[entity] = new UpObject(entity, this)), ); return result; } public getObject(address: string) { if (!this._objects[address]) { this._objects[address] = new UpObject(address, this); } return this._objects[address]; } public get entities(): string[] { return Array.from(new Set(this.entries.map((e) => `@${e.entity}`))); } public get attributes(): string[] { return Array.from(new Set(this.entries.map((e) => e.attribute))); } public get values(): IValue[] { return Array.from(new Set(this.entries.map((e) => e.value))); } } export class UpObject { public readonly address: string; public listing: UpListing | undefined; constructor(address: string, listing?: UpListing) { this.address = address; this.listing = listing; } public bind(listing: UpListing) { this.listing = listing; } public get attributes() { return (this.listing?.entries || []).filter( (e) => e.entity === this.address, ); } public get backlinks() { return (this.listing?.entries || []).filter( (e) => e.value.c === this.address, ); } private _attr: Record | undefined; public get attr(): Record { if (!this._attr) { const result = {} as { [key: string]: UpEntry[] }; this.attributes.forEach((entry) => { if (!result[entry.attribute]) { result[entry.attribute] = []; } result[entry.attribute].push(entry); }); this.backlinks.forEach((entry) => { const attribute = `~${entry.attribute}`; if (!result[attribute]) { result[attribute] = []; } result[attribute].push(entry); }); this._attr = result; } return this._attr; } public get(attr: string): string | number | null | undefined { return this.attr[attr]?.[0].value.c; } public identify(): string[] { return (this.attr["LBL"] || []).map((e) => String(e.value.c)); } public toString(): string { return [`@${this.address}`, this.identify().join(", ")] .filter(Boolean) .join(" | "); } public asDict() { return { address: this.address, attributes: this.attr, }; } } export class UpEntry extends UpObject implements IEntry { entity: string; attribute: string; value: IValue; provenance: string; timestamp: string; constructor(address: string, entry: IEntry, listing: UpListing) { super(address, listing); this.entity = entry.entity; this.attribute = entry.attribute; this.value = entry.value; this.provenance = entry.provenance; this.timestamp = entry.timestamp; } public toString(): string { return `(${this.entity} ${this.attribute} ${this.value.c} [${this.value.t}])`; } }