|
| 1 | +import { CONSTELLATION_HOST } from '#shared/utils/constants' |
| 2 | +import type { CachedFetchFunction } from './fetch-cache-config' |
| 3 | + |
| 4 | +export type Backlink = { |
| 5 | + did: string |
| 6 | + collection: string |
| 7 | + rkey: string |
| 8 | +} |
| 9 | + |
| 10 | +export type BacklinksResponse = { |
| 11 | + total: number |
| 12 | + records: Backlink[] |
| 13 | + cursor: string | undefined |
| 14 | +} |
| 15 | + |
| 16 | +export type LinksDistinctDidsResponse = { |
| 17 | + total: number |
| 18 | + linking_dids: string[] |
| 19 | + cursor: string | undefined |
| 20 | +} |
| 21 | + |
| 22 | +export type AllLinksResponse = { |
| 23 | + links: Record< |
| 24 | + string, |
| 25 | + Record< |
| 26 | + string, |
| 27 | + { |
| 28 | + records: number |
| 29 | + distinct_dids: number |
| 30 | + } |
| 31 | + > |
| 32 | + > |
| 33 | +} |
| 34 | + |
| 35 | +const HEADERS = { 'User-Agent': 'npmx' } |
| 36 | + |
| 37 | +/** @public */ |
| 38 | +export class Constellation { |
| 39 | + private readonly cachedFetch: CachedFetchFunction |
| 40 | + constructor(fetch: CachedFetchFunction) { |
| 41 | + this.cachedFetch = fetch |
| 42 | + } |
| 43 | + |
| 44 | + /** |
| 45 | + * Gets backlinks from constellation |
| 46 | + * https://constellation.microcosm.blue/xrpc/blue.microcosm.links.getBacklinks?subject=at%3A%2F%2Fdid%3Aplc%3Aa4pqq234yw7fqbddawjo7y35%2Fapp.bsky.feed.post%2F3m237ilwc372e&source=app.bsky.feed.like%3Asubject.uri&limit=16 |
| 47 | + * @param subject - A uri encoded link. did, url, or at-uri |
| 48 | + * @param collection - The lexicon collection to check like dev.npmx.feed.like |
| 49 | + * @param recordPath - Where in the record to check for the subject |
| 50 | + * @param limit - The number of backlinks to return |
| 51 | + * @param cursor - The cursor to use for pagination |
| 52 | + * @param reverse - Whether to reverse the order of the results |
| 53 | + * @param filterByDids - An array of dids to filter by in the results |
| 54 | + * @param ttl - The ttl to use for the cache |
| 55 | + */ |
| 56 | + async getBackLinks( |
| 57 | + subject: string, |
| 58 | + collection: string, |
| 59 | + recordPath: string, |
| 60 | + limit = 16, |
| 61 | + cursor?: string, |
| 62 | + reverse = false, |
| 63 | + filterByDids: [string][] = [], |
| 64 | + ttl: number | undefined = undefined, |
| 65 | + ) { |
| 66 | + const source = encodeURIComponent(`${collection}:${recordPath}`) |
| 67 | + let urlToCall = `https://${CONSTELLATION_HOST}/xrpc/blue.microcosm.links.getBacklinks?subject=${encodeURIComponent(subject)}&source=${source}&limit=${limit}` |
| 68 | + if (cursor) urlToCall += `&cursor=${cursor}` |
| 69 | + if (reverse) urlToCall += '&reverse=true' |
| 70 | + filterByDids.forEach(did => (urlToCall += `&did=${did}`)) |
| 71 | + |
| 72 | + return await this.cachedFetch<BacklinksResponse>(urlToCall, { headers: HEADERS }, ttl) |
| 73 | + } |
| 74 | + |
| 75 | + /** |
| 76 | + * Gets the distinct dids that link to a target record |
| 77 | + * @param target - A uri encoded link. did, url, or at-uri |
| 78 | + * @param collection - The lexicon collection to check like dev.npmx.feed.like |
| 79 | + * @param recordPath - Where in the record to check for the subject |
| 80 | + * @param limit - The number of distinct dids to return |
| 81 | + * @param cursor - The cursor to use for pagination |
| 82 | + * @param ttl - The ttl to use for the cache |
| 83 | + */ |
| 84 | + async getLinksDistinctDids( |
| 85 | + target: string, |
| 86 | + collection: string, |
| 87 | + recordPath: string, |
| 88 | + limit: number = 16, |
| 89 | + cursor?: string, |
| 90 | + ttl: number | undefined = undefined, |
| 91 | + ) { |
| 92 | + let urlToCall = `https://${CONSTELLATION_HOST}/links/distinct-dids?target=${encodeURIComponent(target)}&collection=${collection}&path=${recordPath}&limit=${limit}` |
| 93 | + if (cursor) urlToCall += `&cursor=${cursor}` |
| 94 | + return await this.cachedFetch<LinksDistinctDidsResponse>(urlToCall, { headers: HEADERS }, ttl) |
| 95 | + } |
| 96 | + |
| 97 | + /** |
| 98 | + * Gets all links from constellation and their counts |
| 99 | + * @param target - A uri encoded link. did, url, or at-uri |
| 100 | + * @param ttl - The ttl to use for the cache |
| 101 | + */ |
| 102 | + async getAllLinks(target: string, ttl: number | undefined = undefined) { |
| 103 | + return await this.cachedFetch<AllLinksResponse>( |
| 104 | + `https://${CONSTELLATION_HOST}/links/all?target=${target}`, |
| 105 | + { headers: HEADERS }, |
| 106 | + ttl, |
| 107 | + ) |
| 108 | + } |
| 109 | +} |
0 commit comments