useBlockLinks.ts
1 import useSWR from 'swr'; 2 import { 3 getLinksFromApiV1LinksFromBlockIdGet, 4 getLinksToApiV1LinksToBlockIdGet 5 } from '@/data/v1-links'; 6 import { fetchLinks } from '@/utils/links'; 7 import type { GetLinksFromApiV1LinksFromBlockIdGetParams } from '@/data/models/getLinksFromApiV1LinksFromBlockIdGetParams'; 8 import type { GetLinksToApiV1LinksToBlockIdGetParams } from '@/data/models/getLinksToApiV1LinksToBlockIdGetParams'; 9 import type { BlockLink } from '@/data/models/blockLink'; 10 import type { PaginatedLinksResponse } from '@/data/models/paginatedLinksResponse'; 11 12 /** 13 * Hook for fetching all block links with pagination support 14 * @param branch - Optional branch name to fetch links from (defaults to 'main') 15 * @param namespace - Optional namespace to filter links (defaults to 'legacy') 16 * @param cursor - Optional cursor for pagination 17 * @param limit - Optional limit for number of results 18 */ 19 export function useLinks( 20 branch?: string, 21 namespace?: string, 22 cursor?: string, 23 limit?: number 24 ) { 25 const key = [ 26 'links', 27 ...(branch ? [branch] : []), 28 ...(namespace ? [namespace] : []), 29 ...(cursor ? [cursor] : []), 30 ...(limit ? [limit.toString()] : []) 31 ]; 32 const { data, error, isLoading, mutate } = useSWR(key, () => 33 fetchLinks(branch, namespace, cursor, limit) 34 ); 35 36 return { 37 links: data?.links as BlockLink[] | undefined, 38 nextCursor: data?.next_cursor, 39 pageSize: data?.page_size, 40 totalAvailable: data?.total_available, 41 isLoading, 42 isError: error, 43 mutate 44 }; 45 } 46 47 /** 48 * Hook for fetching links from a specific block (outbound links) 49 */ 50 export function useLinksFrom( 51 blockId: string, 52 params?: GetLinksFromApiV1LinksFromBlockIdGetParams 53 ) { 54 const { data, error, isLoading, mutate } = useSWR( 55 blockId ? ['links-from', blockId, params] : null, 56 async () => { 57 const response = await getLinksFromApiV1LinksFromBlockIdGet(blockId, params); 58 if (response.status === 200) { 59 return response.data as PaginatedLinksResponse; 60 } 61 throw new Error(`Failed to fetch links: ${response.status}`); 62 } 63 ); 64 65 return { 66 links: data?.links as BlockLink[] | undefined, 67 nextCursor: data?.next_cursor, 68 pageSize: data?.page_size, 69 totalAvailable: data?.total_available, 70 isLoading, 71 isError: error, 72 mutate 73 }; 74 } 75 76 /** 77 * Hook for fetching links to a specific block (inbound links) 78 */ 79 export function useLinksTo( 80 blockId: string, 81 params?: GetLinksToApiV1LinksToBlockIdGetParams 82 ) { 83 const { data, error, isLoading, mutate } = useSWR( 84 blockId ? ['links-to', blockId, params] : null, 85 async () => { 86 const response = await getLinksToApiV1LinksToBlockIdGet(blockId, params); 87 if (response.status === 200) { 88 return response.data as PaginatedLinksResponse; 89 } 90 throw new Error(`Failed to fetch links: ${response.status}`); 91 } 92 ); 93 94 return { 95 links: data?.links as BlockLink[] | undefined, 96 nextCursor: data?.next_cursor, 97 pageSize: data?.page_size, 98 totalAvailable: data?.total_available, 99 isLoading, 100 isError: error, 101 mutate 102 }; 103 } 104 105 /** 106 * Hook for fetching both inbound and outbound links for a block 107 */ 108 export function useBlockLinks( 109 blockId: string, 110 params?: { 111 from?: GetLinksFromApiV1LinksFromBlockIdGetParams; 112 to?: GetLinksToApiV1LinksToBlockIdGetParams; 113 } 114 ) { 115 const linksFrom = useLinksFrom(blockId, params?.from); 116 const linksTo = useLinksTo(blockId, params?.to); 117 118 return { 119 linksFrom: linksFrom.links, 120 linksTo: linksTo.links, 121 fromPagination: { 122 nextCursor: linksFrom.nextCursor, 123 pageSize: linksFrom.pageSize, 124 totalAvailable: linksFrom.totalAvailable 125 }, 126 toPagination: { 127 nextCursor: linksTo.nextCursor, 128 pageSize: linksTo.pageSize, 129 totalAvailable: linksTo.totalAvailable 130 }, 131 isLoading: linksFrom.isLoading || linksTo.isLoading, 132 isError: linksFrom.isError || linksTo.isError, 133 mutate: () => { 134 linksFrom.mutate(); 135 linksTo.mutate(); 136 } 137 }; 138 }