From cce0c2cdd5070b09f0cb52934787f40e9224bfda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Ml=C3=A1dek?= Date: Sat, 18 Dec 2021 15:12:22 +0100 Subject: [PATCH] basic object-based js API --- tools/upend_js/index.ts | 88 ++++++++++++++++++++++++++++++---------- tools/upend_js/test.ts | 19 +++++---- tools/upend_js/types.ts | 2 +- tools/upend_js/yarn.lock | 2 +- ui/src/lib/entity.ts | 19 ++++----- ui/yarn.lock | 4 +- 6 files changed, 91 insertions(+), 43 deletions(-) diff --git a/tools/upend_js/index.ts b/tools/upend_js/index.ts index 5c8cdfa..5cd81ab 100644 --- a/tools/upend_js/index.ts +++ b/tools/upend_js/index.ts @@ -1,30 +1,76 @@ -import type { Address, IEntry, ListingResult, OrderedListing } from "./types"; +import type { + Address, + IEntry, + ListingResult, + OrderedListing, + 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(b.value.c)) - .sort(([_, a], [__, b]) => String(a.value.t).localeCompare(b.value.t)) + .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 function asDict(attributes: IEntry[]) { - const result = {} as { [key: string]: { [key: string]: unknown } }; - attributes.forEach((entry) => { - if (!result[entry.entity]) { - result[entry.entity] = {}; - } - if (result[entry.entity][entry.attribute]) { - if (!Array.isArray(result[entry.entity][entry.attribute])) { - result[entry.entity][entry.attribute] = [ - result[entry.entity][entry.attribute], - ]; - } - (result[entry.entity][entry.attribute] as unknown[]).push(entry.value.c); - } else { - result[entry.entity][entry.attribute] = entry.value.c; - } - }); +export class UpListing { + private entries: UpEntry[]; - return result; + 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)); + } +} + +export class UpObject { + public readonly address; + + constructor(address: string) { + this.address = address; + } + + public attr(entries: UpEntry[]) { + const result = {} as { [key: string]: UpEntry[] }; + entries + .filter((e) => e.entity == this.address) + .forEach((entry) => { + if (!result[entry.attribute]) { + result[entry.attribute] = []; + } + + result[entry.attribute].push(entry); + }); + + return result; + } + + public asDict(entries: UpEntry[]) { + return { + address: this.address, + attributes: this.attr(entries), + }; + } +} + +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; + } } diff --git a/tools/upend_js/test.ts b/tools/upend_js/test.ts index 5630317..8f0d197 100644 --- a/tools/upend_js/test.ts +++ b/tools/upend_js/test.ts @@ -1,7 +1,7 @@ import test from "ava"; import http from "http"; -import { asDict, listingAsOrdered } from "."; -import { ListingResult, OrderedListing } from "./types"; +import { UpObject, UpEntry, UpListing } from "."; +import type { Address, IEntry, ListingResult } from "./types"; function fetchJSON(url: string): Promise { return new Promise((resolve, reject) => { @@ -23,12 +23,17 @@ function fetchJSON(url: string): Promise { }); } -test("my passing test", async (t) => { - const data = (await fetchJSON( - "http://localhost:8093/api/hier/NATIVE" - )) as ListingResult; +test("basic hier listing", async (t) => { + const data = (await fetchJSON("http://localhost:8093/api/hier/NATIVE")) as { + target: Address; + entries: IEntry[]; + }; - console.log(asDict(Object.values(data))); + const native = new UpObject(data.target); + + // console.log(native.asDict(data.entries)); + + // console.log(asDict(Object.values(data))); t.pass(); }); diff --git a/tools/upend_js/types.ts b/tools/upend_js/types.ts index 2bdd46f..7b825f7 100644 --- a/tools/upend_js/types.ts +++ b/tools/upend_js/types.ts @@ -4,7 +4,7 @@ export type VALUE_TYPE = "Value" | "Address" | "Invalid"; export interface IEntry { entity: Address; attribute: string; - value: { t: VALUE_TYPE; c: string }; + value: { t: VALUE_TYPE; c: string | number }; } export interface ListingResult { diff --git a/tools/upend_js/yarn.lock b/tools/upend_js/yarn.lock index c8fedc0..27d75ce 100644 --- a/tools/upend_js/yarn.lock +++ b/tools/upend_js/yarn.lock @@ -2885,7 +2885,7 @@ __metadata: "typescript@patch:typescript@^4.4.4#~builtin": version: 4.4.4 - resolution: "typescript@patch:typescript@npm%3A4.4.4#~builtin::version=4.4.4&hash=493e53" + resolution: "typescript@patch:typescript@npm%3A4.4.4#~builtin::version=4.4.4&hash=ddd1e8" bin: tsc: bin/tsc tsserver: bin/tsserver diff --git a/ui/src/lib/entity.ts b/ui/src/lib/entity.ts index 61ad3e0..82b39e6 100644 --- a/ui/src/lib/entity.ts +++ b/ui/src/lib/entity.ts @@ -2,9 +2,8 @@ import { useSWR } from "../util/fetch"; import { derived, Readable, readable, writable } from "svelte/store"; import type { IEntry, ListingResult, OrderedListing } from "upend/types"; -import { listingAsOrdered } from "upend"; +import { listingAsOrdered, UpEntry } from "upend"; import LRU from "lru-cache"; -import { attr } from "svelte/internal"; export function useEntity( address: string | (() => string), @@ -82,13 +81,13 @@ export async function queryOnce(query: string): Promise { } export async function identify( - attributes: OrderedListing, - backlinks: OrderedListing + attributes: UpEntry[], + backlinks: UpEntry[] ): Promise { // Get all entries where the object is linked const hasEntries = backlinks - .filter(([_, entry]) => entry.attribute === "HAS") - .map(([addr, _]) => addr); + .filter((entry) => entry.attribute === "HAS") + .map((entry) => entry.address); // Out of those relations, retrieve their ALIAS attrs const hasAliases = hasEntries.length @@ -97,13 +96,11 @@ export async function identify( ) : []; - const aliasValues = hasAliases.map(([_, entry]) => { - return entry.value.c; - }); + const aliasValues = hasAliases.map(([_, entry]) => String(entry.value.c)); // Return all LBLs concatenated with named aliases return attributes - .filter(([_, attr]) => attr.attribute === "LBL") - .map(([_, attr]) => attr.value.c) + .filter((attr) => attr.attribute === "LBL") + .map((attr) => String(attr.value.c)) .concat(aliasValues); } diff --git a/ui/yarn.lock b/ui/yarn.lock index e417c33..a623d62 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -3301,8 +3301,8 @@ __metadata: "upend@file:../tools/upend_js::locator=svelte-app%40workspace%3A.": version: 0.0.1 - resolution: "upend@file:../tools/upend_js#../tools/upend_js::hash=cc5701&locator=svelte-app%40workspace%3A." - checksum: e0acfc00449acb9243dccbf595de95746469d9ec74dcf064bd5fa17103048396578d4a8530ce68943fb095790e980c04961f0f0fe79f7edc1ed1cbfafddd5766 + resolution: "upend@file:../tools/upend_js#../tools/upend_js::hash=33980e&locator=svelte-app%40workspace%3A." + checksum: 6370b50d9a8c407e5807f62020fa045f0df1ad727b12d6273fe00cf08b47cc75da6d89493538b084ab5fddd66d3e735fcda33e750fe729910e6ee5be6d66d14e languageName: node linkType: hard