feat: improve 🌸

This commit is contained in:
codytseng 2025-10-24 22:41:16 +08:00
parent 36c9796ea1
commit 1274942f64
7 changed files with 166 additions and 107 deletions

View file

@ -0,0 +1,95 @@
import client from '@/services/client.service'
import { getHashFromURL } from 'blossom-client-sdk'
class BlossomService {
static instance: BlossomService
private cacheMap = new Map<
string,
{
pubkey: string
resolve: (url: string) => void
promise: Promise<string>
tried: Set<string>
}
>()
constructor() {
if (!BlossomService.instance) {
BlossomService.instance = this
}
return BlossomService.instance
}
async getValidUrl(url: string, pubkey: string): Promise<string> {
const cache = this.cacheMap.get(url)
if (cache) {
return cache.promise
}
let resolveFunc: (url: string) => void
const promise = new Promise<string>((resolve) => {
resolveFunc = resolve
})
const tried = new Set<string>()
this.cacheMap.set(url, { pubkey, resolve: resolveFunc!, promise, tried })
return url
}
async tryNextUrl(originalUrl: string): Promise<string | null> {
const entry = this.cacheMap.get(originalUrl)
if (!entry) {
return null
}
const { pubkey, tried, resolve } = entry
let oldImageUrl: URL | undefined
let hash: string | null = null
try {
oldImageUrl = new URL(originalUrl)
hash = getHashFromURL(oldImageUrl)
} catch (error) {
console.error('Invalid image URL:', error)
}
if (!pubkey || !hash || !oldImageUrl) {
resolve(originalUrl)
return null
}
const ext = oldImageUrl.pathname.match(/\.\w+$/i)
const blossomServerList = await client.fetchBlossomServerList(pubkey)
const urls = blossomServerList
.map((server) => {
try {
return new URL(server)
} catch (error) {
console.error('Invalid Blossom server URL:', server, error)
return undefined
}
})
.filter((url) => !!url && !tried.has(url.hostname))
const nextUrl = urls[0]
if (!nextUrl) {
resolve(originalUrl)
return null
}
tried.add(nextUrl.hostname)
nextUrl.pathname = '/' + hash + ext
return nextUrl.toString()
}
markAsSuccess(originalUrl: string, successUrl: string) {
const entry = this.cacheMap.get(originalUrl)
if (!entry) return
entry.resolve(successUrl)
if (originalUrl === successUrl) {
this.cacheMap.delete(originalUrl)
}
}
}
const instance = new BlossomService()
export default instance