upend/tools/upend_js/index.ts

140 lines
3.3 KiB
TypeScript
Raw Normal View History

2022-01-28 20:51:34 +01:00
import type { IEntry, IValue, ListingResult } from "./types";
export { UpEndApi } from "./api";
export { Query } from "./query";
2021-12-18 15:12:22 +01:00
export class UpListing {
public readonly entries: UpEntry[];
private _objects: { [key: string]: UpObject } = {};
2021-12-18 15:12:22 +01:00
constructor(listing: ListingResult) {
this.entries = Object.entries(listing).map(
(lr) => new UpEntry(...lr, this),
);
2021-12-18 15:12:22 +01:00
}
public get objects() {
2021-12-18 15:12:22 +01:00
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)),
2021-12-19 11:46:40 +01:00
);
return result;
}
public getObject(address: string) {
if (!this._objects[address]) {
this._objects[address] = new UpObject(address, this);
}
return this._objects[address];
2021-12-18 15:12:22 +01:00
}
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)));
}
2021-12-18 15:12:22 +01:00
}
export class UpObject {
public readonly address: string;
public listing: UpListing | undefined;
2021-12-18 15:12:22 +01:00
constructor(address: string, listing?: UpListing) {
2021-12-18 15:12:22 +01:00
this.address = address;
this.listing = listing;
2021-12-19 11:46:40 +01:00
}
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<string, UpEntry[] | undefined> | undefined;
public get attr(): Record<string, UpEntry[] | undefined> {
2023-12-03 19:28:24 +01:00
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;
2021-12-18 15:12:22 +01:00
}
public get(attr: string): string | number | null | undefined {
return this.attr[attr]?.[0].value.c;
2021-12-19 11:46:40 +01:00
}
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(" | ");
}
2021-12-19 11:46:40 +01:00
public asDict() {
2021-12-18 15:12:22 +01:00
return {
address: this.address,
2021-12-19 11:46:40 +01:00
attributes: this.attr,
2021-12-18 15:12:22 +01:00
};
}
}
export class UpEntry extends UpObject implements IEntry {
entity: string;
attribute: string;
value: IValue;
provenance: string;
timestamp: string;
2021-12-18 15:12:22 +01:00
constructor(address: string, entry: IEntry, listing: UpListing) {
super(address, listing);
2021-12-18 15:12:22 +01:00
this.entity = entry.entity;
this.attribute = entry.attribute;
this.value = entry.value;
this.provenance = entry.provenance;
this.timestamp = entry.timestamp;
2021-12-18 15:12:22 +01:00
}
2021-12-21 14:32:36 +01:00
public toString(): string {
return `(${this.entity} ${this.attribute} ${this.value.c} [${this.value.t}])`;
}
2021-11-11 23:37:42 +01:00
}