[READ-ONLY] a fast, modern browser for the npm registry
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: getting tangled stats from our backend (#981)

authored by

Bailey Townsend and committed by
GitHub
115c1c4a 0d40d1ed

+74 -30
+5 -30
app/composables/useRepoMeta.ts
··· 566 566 }, 567 567 568 568 async fetchMeta(cachedFetch, ref, links, options = {}) { 569 - // Tangled doesn't have a public JSON API, but we can scrape the star count 570 - // from the HTML page (it's in the hx-post URL as countHint=N) 571 569 try { 572 - const { data: html } = await cachedFetch<string>( 573 - `https://tangled.org/${ref.owner}/${ref.repo}`, 574 - { 575 - headers: { 'User-Agent': 'npmx', 'Accept': 'text/html', ...options.headers }, 576 - ...options, 577 - }, 570 + const { data } = await cachedFetch<{ stars: number; forks: number }>( 571 + `/api/atproto/tangled-stats/${ref.owner}/${ref.repo}`, 572 + options, 578 573 REPO_META_TTL, 579 574 ) 580 - // Extracts the at-uri used in atproto 581 - const atUriMatch = html.match(/data-star-subject-at="([^"]+)"/) 582 - // Extract star count from: hx-post="/star?subject=...&countHint=23" 583 - const starMatch = html.match(/countHint=(\d+)/) 584 - //We'll set the stars from tangled's repo page and may override it with constellation if successful 585 - let stars = starMatch?.[1] ? parseInt(starMatch[1], 10) : 0 586 - let forks = 0 587 - const atUri = atUriMatch?.[1] 588 - 589 - if (atUri) { 590 - try { 591 - const constellation = new Constellation(cachedFetch) 592 - //Get counts of records that reference this repo in the atmosphere using constellation 593 - const { data: allLinks } = await constellation.getAllLinks(atUri) 594 - stars = allLinks.links['sh.tangled.feed.star']?.['.subject']?.distinct_dids ?? stars 595 - forks = allLinks.links['sh.tangled.repo']?.['.source']?.distinct_dids ?? stars 596 - } catch { 597 - //failing silently since this is just an enhancement to the information already showing 598 - } 599 - } 600 575 601 576 return { 602 577 provider: 'tangled', 603 578 url: links.repo, 604 - stars, 605 - forks, 579 + stars: data.stars, 580 + forks: data.forks, 606 581 links, 607 582 } 608 583 } catch {
+69
server/api/atproto/tangled-stats/[owner]/[...repo].ts
··· 1 + import type { CachedFetchFunction } from '#shared/utils/fetch-cache-config' 2 + 3 + export default defineCachedEventHandler( 4 + async event => { 5 + let owner = getRouterParam(event, 'owner') 6 + let repo = getRouterParam(event, 'repo') 7 + 8 + let cachedFetch: CachedFetchFunction 9 + if (event.context.cachedFetch) { 10 + cachedFetch = event.context.cachedFetch 11 + } else { 12 + // Fallback: return a function that uses regular $fetch 13 + // (shouldn't happen in normal operation) 14 + cachedFetch = async <T = unknown>( 15 + url: string, 16 + options: Parameters<typeof $fetch>[1] = {}, 17 + _ttl?: number, 18 + ): Promise<CachedFetchResult<T>> => { 19 + const data = (await $fetch<T>(url, options)) as T 20 + return { data, isStale: false, cachedAt: null } 21 + } 22 + } 23 + 24 + try { 25 + // Tangled doesn't have a public JSON API, but we can scrape the star count 26 + // from the HTML page (it's in the hx-post URL as countHint=N) 27 + const { data: html } = await cachedFetch<string>( 28 + `https://tangled.org/${owner}/${repo}`, 29 + { 30 + headers: { 'User-Agent': 'npmx', 'Accept': 'text/html' }, 31 + }, 32 + CACHE_MAX_AGE_ONE_MINUTE * 10, 33 + ) 34 + // Extracts the at-uri used in atproto 35 + const atUriMatch = html.match(/data-star-subject-at="([^"]+)"/) 36 + // Extract star count from: hx-post="/star?subject=...&countHint=23" 37 + const starMatch = html.match(/countHint=(\d+)/) 38 + //We'll set the stars from tangled's repo page and may override it with constellation if successful 39 + let stars = starMatch?.[1] ? parseInt(starMatch[1], 10) : 0 40 + let forks = 0 41 + const atUri = atUriMatch?.[1] 42 + 43 + if (atUri) { 44 + try { 45 + const constellation = new Constellation(cachedFetch) 46 + //Get counts of records that reference this repo in the atmosphere using constellation 47 + const { data: allLinks } = await constellation.getAllLinks(atUri) 48 + stars = allLinks.links['sh.tangled.feed.star']?.['.subject']?.distinct_dids ?? stars 49 + forks = allLinks.links['sh.tangled.repo']?.['.source']?.distinct_dids ?? 0 50 + } catch { 51 + //failing silently since this is just an enhancement to the information already showing 52 + } 53 + } 54 + 55 + return { 56 + stars, 57 + forks, 58 + } 59 + } catch { 60 + return { 61 + stars: 0, 62 + forks: 0, 63 + } 64 + } 65 + }, 66 + { 67 + maxAge: CACHE_MAX_AGE_ONE_MINUTE * 10, 68 + }, 69 + )