(url: string)
| 368 | } |
| 369 | |
| 370 | export function fetchLinkTitle(url: string): Promise<string> { |
| 371 | const normalizedUrl = normalizeExternalUrl(url) |
| 372 | const key = titleCacheKey(normalizedUrl) |
| 373 | |
| 374 | if (!isTitleFetchable(normalizedUrl)) { |
| 375 | return Promise.resolve('') |
| 376 | } |
| 377 | |
| 378 | if (titleCache.has(key)) { |
| 379 | return Promise.resolve(titleCache.get(key) ?? '') |
| 380 | } |
| 381 | |
| 382 | const pending = titleInflight.get(key) |
| 383 | |
| 384 | if (pending) { |
| 385 | return pending |
| 386 | } |
| 387 | |
| 388 | const promise = fetchHtmlTitle(normalizedUrl) |
| 389 | .then(usableTitle) |
| 390 | .catch(() => '') |
| 391 | .then(clean => { |
| 392 | cacheTitle(key, clean) |
| 393 | titleSubs.get(key)?.forEach(sub => sub(clean)) |
| 394 | |
| 395 | return clean |
| 396 | }) |
| 397 | .finally(() => { |
| 398 | titleInflight.delete(key) |
| 399 | }) |
| 400 | |
| 401 | titleInflight.set(key, promise) |
| 402 | |
| 403 | return promise |
| 404 | } |
| 405 | |
| 406 | export function useLinkTitle(url?: null | string): string { |
| 407 | const normalizedUrl = useMemo(() => (url ? normalizeExternalUrl(url) : ''), [url]) |
no test coverage detected