import LRU from "lru-cache"; import { UpListing, UpObject } from "upend"; import type { Address, IJob, InEntry, IValue, ListingResult, PutResult, VaultInfo, StoreInfo, AttributeListingResult, } from "upend/types"; import type { EntityListing } from "./entity"; export const API_URL = "api"; export async function fetchEntity(address: string): Promise { const entityFetch = await fetch(`${API_URL}/obj/${address}`); const entityResult = (await entityFetch.json()) as EntityListing; const entityListing = new UpListing(entityResult.entries); return entityListing.getObject(address); } export async function fetchEntry(address: string) { const response = await fetch(`${API_URL}/raw/${address}`); const data = await response.json(); const listing = new UpListing({ address: data }); return listing.entries[0]; } const queryOnceLRU = new LRU(128); const inFlightRequests: { [key: string]: Promise } = {}; export async function queryOnce(query: string): Promise { const cacheResult = queryOnceLRU.get(query); if (!cacheResult) { if (!inFlightRequests[query]) { console.debug(`Querying: ${query}`); inFlightRequests[query] = new Promise((resolve, reject) => { fetch(`${API_URL}/query`, { method: "POST", body: query, keepalive: true, }) .then(async (response) => { inFlightRequests[query] = null; resolve(new UpListing(await response.json())); }) .catch((err) => reject(err)); }); } else { console.debug(`Chaining request for ${query}...`); } return await inFlightRequests[query]; } else { console.debug(`Returning cached: ${query}`); return cacheResult; } } export async function putEntry(entry: InEntry): Promise { const response = await fetch(`${API_URL}/obj`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(entry), }); return await response.json(); } export async function putEntityAttribute( entity: Address, attribute: string, value: IValue ): Promise
{ const response = await fetch(`${API_URL}/obj/${entity}/${attribute}`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(value), }); return await response.json(); } export async function uploadFile(file: File): Promise { const formData = new FormData(); formData.append("file", file); const response = await fetch(`${API_URL}/obj`, { method: "PUT", body: formData, }); if (!response.ok) { throw Error(await response.text()); } return await response.json(); } export async function deleteEntry(address: Address): Promise { await fetch(`${API_URL}/obj/${address}`, { method: "DELETE" }); } export async function getRaw(address: Address, preview = false) { return await fetch(`${API_URL}/${preview ? "thumb" : "raw"}/${address}`); } export async function refreshVault() { return await fetch(`${API_URL}/refresh`, { method: "POST" }); } export async function nativeOpen(address: Address) { return fetch(`${API_URL}/raw/${address}?native=1`); } export async function fetchRoots(): Promise { const response = await fetch(`${API_URL}/hier_roots`); return await response.json(); } export async function fetchJobs(): Promise { const response = await fetch(`${API_URL}/jobs`); return await response.json(); } export async function fetchAllAttributes(): Promise { const response = await fetch(`${API_URL}/all/attributes`); return await response.json(); } export async function fetchInfo(): Promise { const response = await fetch(`${API_URL}/info`); return await response.json(); } export async function fetchStoreInfo(): Promise<{ [key: string]: StoreInfo }> { const response = await fetch(`${API_URL}/store`); return await response.json(); } export async function getAddress(input: { attribute: string }): Promise { const response = await fetch( `${API_URL}/address?attribute=${input.attribute}` ); return await response.json(); }