This repository has no description
0

Configure Feed

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

semble / src / webapp / api-client / clients / QueryClient.ts
24 kB 649 lines
1import { BaseClient } from './BaseClient'; 2import { 3 GetUrlMetadataResponse, 4 GetUrlCardsResponse, 5 GetUrlCardViewResponse, 6 GetLibrariesForCardResponse, 7 GetProfileResponse, 8 GetCollectionPageResponse, 9 GetCollectionsResponse, 10 GetUrlStatusForMyLibraryResponse, 11 GetUrlMetadataParams, 12 GetMyUrlCardsParams, 13 GetUrlCardsParams, 14 GetCollectionPageParams, 15 GetMyCollectionsParams, 16 GetCollectionsParams, 17 GetCollectionPageByAtUriParams, 18 GetProfileParams, 19 GetUrlStatusForMyLibraryParams, 20 GetLibrariesForUrlParams, 21 GetLibrariesForUrlResponse, 22 GetNoteCardsForUrlParams, 23 GetNoteCardsForUrlResponse, 24 GetCollectionsForUrlParams, 25 GetCollectionsForUrlResponse, 26 GetSimilarUrlsForUrlParams, 27 GetSimilarUrlsForUrlResponse, 28 SemanticSearchUrlsParams, 29 SemanticSearchUrlsResponse, 30 SearchBskyPostsForUrlParams, 31 SearchBskyPostsForUrlResponse, 32 SearchAtProtoAccountsParams, 33 SearchAtProtoAccountsResponse, 34 SearchLeafletDocsForUrlParams, 35 SearchLeafletDocsForUrlResponse, 36 GetOpenCollectionsWithContributorParams, 37 GetFollowingUsersParams, 38 GetFollowingUsersResponse, 39 GetFollowersParams, 40 GetFollowersResponse, 41 GetFollowingCollectionsParams, 42 GetFollowingCollectionsResponse, 43 GetCollectionFollowersParams, 44 GetCollectionFollowersResponse, 45 GetFollowingCountParams, 46 GetFollowersCountParams, 47 GetFollowingCollectionsCountParams, 48 GetCollectionFollowersCountParams, 49 GetFollowCountResponse, 50 GetCollectionContributorsParams, 51 GetCollectionContributorsResponse, 52 GetConnectionsParams, 53 GetConnectionsResponse, 54 SearchUrlsParams, 55 SearchUrlsResponse, 56 GetGraphDataParams, 57 GetGraphDataResponse, 58 GetConnectionsForUrlParams, 59 GetConnectionsForUrlResponse, 60 GetUrlGraphDataParams, 61} from '@semble/types'; 62 63export class QueryClient extends BaseClient { 64 async getUrlMetadata( 65 params: GetUrlMetadataParams, 66 ): Promise<GetUrlMetadataResponse> { 67 const queryParams = new URLSearchParams({ url: params.url }); 68 if (params.includeStats !== undefined) { 69 queryParams.set('includeStats', params.includeStats.toString()); 70 } 71 return this.request<GetUrlMetadataResponse>( 72 'GET', 73 `/api/cards/metadata?${queryParams}`, 74 ); 75 } 76 77 async getMyUrlCards( 78 params?: GetMyUrlCardsParams, 79 ): Promise<GetUrlCardsResponse> { 80 const searchParams = new URLSearchParams(); 81 if (params?.page) searchParams.set('page', params.page.toString()); 82 if (params?.limit) searchParams.set('limit', params.limit.toString()); 83 if (params?.sortBy) searchParams.set('sortBy', params.sortBy); 84 if (params?.sortOrder) searchParams.set('sortOrder', params.sortOrder); 85 if (params?.urlType) searchParams.set('urlType', params.urlType); 86 if (params?.uncollected) searchParams.set('uncollected', 'true'); 87 88 const queryString = searchParams.toString(); 89 const endpoint = queryString 90 ? `/api/cards/my?${queryString}` 91 : '/api/cards/my'; 92 93 return this.request<GetUrlCardsResponse>('GET', endpoint); 94 } 95 96 async getUserUrlCards( 97 params: GetUrlCardsParams, 98 ): Promise<GetUrlCardsResponse> { 99 const searchParams = new URLSearchParams(); 100 if (params.page) searchParams.set('page', params.page.toString()); 101 if (params.limit) searchParams.set('limit', params.limit.toString()); 102 if (params.sortBy) searchParams.set('sortBy', params.sortBy); 103 if (params.sortOrder) searchParams.set('sortOrder', params.sortOrder); 104 if (params.urlType) searchParams.set('urlType', params.urlType); 105 if (params.uncollected) searchParams.set('uncollected', 'true'); 106 107 const queryString = searchParams.toString(); 108 const endpoint = queryString 109 ? `/api/cards/user/${params.identifier}?${queryString}` 110 : `/api/cards/user/${params.identifier}`; 111 112 return this.request<GetUrlCardsResponse>('GET', endpoint); 113 } 114 115 async getUrlCardView(cardId: string): Promise<GetUrlCardViewResponse> { 116 return this.request<GetUrlCardViewResponse>('GET', `/api/cards/${cardId}`); 117 } 118 119 async getLibrariesForCard( 120 cardId: string, 121 ): Promise<GetLibrariesForCardResponse> { 122 return this.request<GetLibrariesForCardResponse>( 123 'GET', 124 `/api/cards/${cardId}/libraries`, 125 ); 126 } 127 128 async getMyProfile(params?: { 129 includeStats?: boolean; 130 }): Promise<GetProfileResponse> { 131 const queryParams = new URLSearchParams(); 132 if (params?.includeStats !== undefined) { 133 queryParams.set('includeStats', params.includeStats.toString()); 134 } 135 const queryString = queryParams.toString(); 136 return this.request<GetProfileResponse>( 137 'GET', 138 `/api/users/me${queryString ? `?${queryString}` : ''}`, 139 ); 140 } 141 142 async getUserProfile(params: GetProfileParams): Promise<GetProfileResponse> { 143 const queryParams = new URLSearchParams(); 144 if (params.includeStats !== undefined) { 145 queryParams.set('includeStats', params.includeStats.toString()); 146 } 147 const queryString = queryParams.toString(); 148 return this.request<GetProfileResponse>( 149 'GET', 150 `/api/users/${params.identifier}${queryString ? `?${queryString}` : ''}`, 151 ); 152 } 153 154 async getCollectionPage( 155 collectionId: string, 156 params?: GetCollectionPageParams, 157 ): Promise<GetCollectionPageResponse> { 158 const searchParams = new URLSearchParams(); 159 if (params?.page) searchParams.set('page', params.page.toString()); 160 if (params?.limit) searchParams.set('limit', params.limit.toString()); 161 if (params?.sortBy) searchParams.set('sortBy', params.sortBy); 162 if (params?.sortOrder) searchParams.set('sortOrder', params.sortOrder); 163 if (params?.urlType) searchParams.set('urlType', params.urlType); 164 165 const queryString = searchParams.toString(); 166 const endpoint = queryString 167 ? `/api/collections/${collectionId}?${queryString}` 168 : `/api/collections/${collectionId}`; 169 170 return this.request<GetCollectionPageResponse>('GET', endpoint); 171 } 172 173 async getCollectionPageByAtUri( 174 params: GetCollectionPageByAtUriParams, 175 ): Promise<GetCollectionPageResponse> { 176 const { handle, recordKey, ...queryParams } = params; 177 const searchParams = new URLSearchParams(); 178 179 if (queryParams.page) searchParams.set('page', queryParams.page.toString()); 180 if (queryParams.limit) 181 searchParams.set('limit', queryParams.limit.toString()); 182 if (queryParams.sortBy) searchParams.set('sortBy', queryParams.sortBy); 183 if (queryParams.sortOrder) 184 searchParams.set('sortOrder', queryParams.sortOrder); 185 if (queryParams.urlType) searchParams.set('urlType', queryParams.urlType); 186 187 const queryString = searchParams.toString(); 188 const endpoint = queryString 189 ? `/api/collections/at/${handle}/${recordKey}?${queryString}` 190 : `/api/collections/at/${handle}/${recordKey}`; 191 192 return this.request<GetCollectionPageResponse>('GET', endpoint); 193 } 194 195 async getMyCollections( 196 params?: GetMyCollectionsParams, 197 ): Promise<GetCollectionsResponse> { 198 const searchParams = new URLSearchParams(); 199 if (params?.page) searchParams.set('page', params.page.toString()); 200 if (params?.limit) searchParams.set('limit', params.limit.toString()); 201 if (params?.sortBy) searchParams.set('sortBy', params.sortBy); 202 if (params?.sortOrder) searchParams.set('sortOrder', params.sortOrder); 203 if (params?.searchText) searchParams.set('searchText', params.searchText); 204 205 const queryString = searchParams.toString(); 206 const endpoint = queryString 207 ? `/api/collections?${queryString}` 208 : '/api/collections'; 209 210 return this.request<GetCollectionsResponse>('GET', endpoint); 211 } 212 213 async getUserCollections( 214 params: GetCollectionsParams, 215 ): Promise<GetCollectionsResponse> { 216 const searchParams = new URLSearchParams(); 217 if (params.page) searchParams.set('page', params.page.toString()); 218 if (params.limit) searchParams.set('limit', params.limit.toString()); 219 if (params.sortBy) searchParams.set('sortBy', params.sortBy); 220 if (params.sortOrder) searchParams.set('sortOrder', params.sortOrder); 221 if (params.searchText) searchParams.set('searchText', params.searchText); 222 223 const queryString = searchParams.toString(); 224 const endpoint = queryString 225 ? `/api/collections/user/${params.identifier}?${queryString}` 226 : `/api/collections/user/${params.identifier}`; 227 228 return this.request<GetCollectionsResponse>('GET', endpoint); 229 } 230 231 async getUrlStatusForMyLibrary( 232 params: GetUrlStatusForMyLibraryParams, 233 ): Promise<GetUrlStatusForMyLibraryResponse> { 234 const searchParams = new URLSearchParams({ url: params.url }); 235 return this.request<GetUrlStatusForMyLibraryResponse>( 236 'GET', 237 `/api/cards/library/status?${searchParams}`, 238 ); 239 } 240 241 async getLibrariesForUrl( 242 params: GetLibrariesForUrlParams, 243 ): Promise<GetLibrariesForUrlResponse> { 244 const searchParams = new URLSearchParams({ url: params.url }); 245 if (params.page) searchParams.set('page', params.page.toString()); 246 if (params.limit) searchParams.set('limit', params.limit.toString()); 247 if (params.sortBy) searchParams.set('sortBy', params.sortBy); 248 if (params.sortOrder) searchParams.set('sortOrder', params.sortOrder); 249 250 return this.request<GetLibrariesForUrlResponse>( 251 'GET', 252 `/api/cards/libraries/url?${searchParams}`, 253 ); 254 } 255 256 async getNoteCardsForUrl( 257 params: GetNoteCardsForUrlParams, 258 ): Promise<GetNoteCardsForUrlResponse> { 259 const searchParams = new URLSearchParams({ url: params.url }); 260 if (params.page) searchParams.set('page', params.page.toString()); 261 if (params.limit) searchParams.set('limit', params.limit.toString()); 262 if (params.sortBy) searchParams.set('sortBy', params.sortBy); 263 if (params.sortOrder) searchParams.set('sortOrder', params.sortOrder); 264 265 return this.request<GetNoteCardsForUrlResponse>( 266 'GET', 267 `/api/cards/notes/url?${searchParams}`, 268 ); 269 } 270 271 async getCollectionsForUrl( 272 params: GetCollectionsForUrlParams, 273 ): Promise<GetCollectionsForUrlResponse> { 274 const searchParams = new URLSearchParams({ url: params.url }); 275 if (params.page) searchParams.set('page', params.page.toString()); 276 if (params.limit) searchParams.set('limit', params.limit.toString()); 277 if (params.sortBy) searchParams.set('sortBy', params.sortBy); 278 if (params.sortOrder) searchParams.set('sortOrder', params.sortOrder); 279 280 return this.request<GetCollectionsForUrlResponse>( 281 'GET', 282 `/api/collections/url?${searchParams}`, 283 ); 284 } 285 286 async getSimilarUrlsForUrl( 287 params: GetSimilarUrlsForUrlParams, 288 ): Promise<GetSimilarUrlsForUrlResponse> { 289 const searchParams = new URLSearchParams({ url: params.url }); 290 if (params.page) searchParams.set('page', params.page.toString()); 291 if (params.limit) searchParams.set('limit', params.limit.toString()); 292 if (params.sortBy) searchParams.set('sortBy', params.sortBy); 293 if (params.sortOrder) searchParams.set('sortOrder', params.sortOrder); 294 if (params.threshold) 295 searchParams.set('threshold', params.threshold.toString()); 296 if (params.urlType) searchParams.set('urlType', params.urlType); 297 298 return this.request<GetSimilarUrlsForUrlResponse>( 299 'GET', 300 `/api/search/similar-urls?${searchParams}`, 301 ); 302 } 303 304 async semanticSearchUrls( 305 params: SemanticSearchUrlsParams, 306 ): Promise<SemanticSearchUrlsResponse> { 307 const searchParams = new URLSearchParams({ query: params.query }); 308 if (params.page) searchParams.set('page', params.page.toString()); 309 if (params.limit) searchParams.set('limit', params.limit.toString()); 310 if (params.sortBy) searchParams.set('sortBy', params.sortBy); 311 if (params.sortOrder) searchParams.set('sortOrder', params.sortOrder); 312 if (params.threshold) 313 searchParams.set('threshold', params.threshold.toString()); 314 if (params.urlType) searchParams.set('urlType', params.urlType); 315 if (params.identifier) searchParams.set('identifier', params.identifier); 316 317 return this.request<SemanticSearchUrlsResponse>( 318 'GET', 319 `/api/search/semantic?${searchParams}`, 320 ); 321 } 322 323 async searchBskyPosts( 324 params: SearchBskyPostsForUrlParams, 325 ): Promise<SearchBskyPostsForUrlResponse> { 326 const searchParams = new URLSearchParams({ q: params.q }); 327 if (params.sort) searchParams.set('sort', params.sort); 328 if (params.since) searchParams.set('since', params.since); 329 if (params.until) searchParams.set('until', params.until); 330 if (params.mentions) searchParams.set('mentions', params.mentions); 331 if (params.author) searchParams.set('author', params.author); 332 if (params.lang) searchParams.set('lang', params.lang); 333 if (params.domain) searchParams.set('domain', params.domain); 334 if (params.url) searchParams.set('url', params.url); 335 if (params.tag) { 336 params.tag.forEach((t) => searchParams.append('tag', t)); 337 } 338 if (params.limit) searchParams.set('limit', params.limit.toString()); 339 if (params.cursor) searchParams.set('cursor', params.cursor); 340 341 return this.request<SearchBskyPostsForUrlResponse>( 342 'GET', 343 `/api/search/bsky-posts?${searchParams}`, 344 ); 345 } 346 347 async searchAtProtoAccounts( 348 params: SearchAtProtoAccountsParams, 349 ): Promise<SearchAtProtoAccountsResponse> { 350 const searchParams = new URLSearchParams(); 351 if (params.term) searchParams.set('term', params.term); 352 if (params.q) searchParams.set('q', params.q); 353 if (params.limit) searchParams.set('limit', params.limit.toString()); 354 if (params.cursor) searchParams.set('cursor', params.cursor); 355 356 return this.request<SearchAtProtoAccountsResponse>( 357 'GET', 358 `/api/search/accounts?${searchParams}`, 359 ); 360 } 361 362 async searchLeafletDocs( 363 params: SearchLeafletDocsForUrlParams, 364 ): Promise<SearchLeafletDocsForUrlResponse> { 365 const searchParams = new URLSearchParams({ url: params.url }); 366 if (params.limit) searchParams.set('limit', params.limit.toString()); 367 if (params.cursor) searchParams.set('cursor', params.cursor); 368 369 return this.request<SearchLeafletDocsForUrlResponse>( 370 'GET', 371 `/api/search/leaflet-docs?${searchParams}`, 372 ); 373 } 374 375 async getOpenCollectionsWithContributor( 376 params: GetOpenCollectionsWithContributorParams, 377 ): Promise<GetCollectionsResponse> { 378 const searchParams = new URLSearchParams(); 379 if (params.page) searchParams.set('page', params.page.toString()); 380 if (params.limit) searchParams.set('limit', params.limit.toString()); 381 if (params.sortBy) searchParams.set('sortBy', params.sortBy); 382 if (params.sortOrder) searchParams.set('sortOrder', params.sortOrder); 383 384 const queryString = searchParams.toString(); 385 const endpoint = queryString 386 ? `/api/collections/contributed/${params.identifier}?${queryString}` 387 : `/api/collections/contributed/${params.identifier}`; 388 389 return this.request<GetCollectionsResponse>('GET', endpoint); 390 } 391 392 // Follow query methods 393 async getFollowingUsers( 394 params: GetFollowingUsersParams, 395 ): Promise<GetFollowingUsersResponse> { 396 const searchParams = new URLSearchParams(); 397 if (params.page) searchParams.set('page', params.page.toString()); 398 if (params.limit) searchParams.set('limit', params.limit.toString()); 399 400 const queryString = searchParams.toString(); 401 const endpoint = queryString 402 ? `/api/users/${params.identifier}/following?${queryString}` 403 : `/api/users/${params.identifier}/following`; 404 405 return this.request<GetFollowingUsersResponse>('GET', endpoint); 406 } 407 408 async getFollowers( 409 params: GetFollowersParams, 410 ): Promise<GetFollowersResponse> { 411 const searchParams = new URLSearchParams(); 412 if (params.page) searchParams.set('page', params.page.toString()); 413 if (params.limit) searchParams.set('limit', params.limit.toString()); 414 415 const queryString = searchParams.toString(); 416 const endpoint = queryString 417 ? `/api/users/${params.identifier}/followers?${queryString}` 418 : `/api/users/${params.identifier}/followers`; 419 420 return this.request<GetFollowersResponse>('GET', endpoint); 421 } 422 423 async getFollowingCollections( 424 params: GetFollowingCollectionsParams, 425 ): Promise<GetFollowingCollectionsResponse> { 426 const searchParams = new URLSearchParams(); 427 if (params.page) searchParams.set('page', params.page.toString()); 428 if (params.limit) searchParams.set('limit', params.limit.toString()); 429 430 const queryString = searchParams.toString(); 431 const endpoint = queryString 432 ? `/api/users/${params.identifier}/following-collections?${queryString}` 433 : `/api/users/${params.identifier}/following-collections`; 434 435 return this.request<GetFollowingCollectionsResponse>('GET', endpoint); 436 } 437 438 async getCollectionFollowers( 439 params: GetCollectionFollowersParams, 440 ): Promise<GetCollectionFollowersResponse> { 441 const searchParams = new URLSearchParams(); 442 if (params.page) searchParams.set('page', params.page.toString()); 443 if (params.limit) searchParams.set('limit', params.limit.toString()); 444 445 const queryString = searchParams.toString(); 446 const endpoint = queryString 447 ? `/api/collections/${params.collectionId}/followers?${queryString}` 448 : `/api/collections/${params.collectionId}/followers`; 449 450 return this.request<GetCollectionFollowersResponse>('GET', endpoint); 451 } 452 453 async getFollowingCount( 454 params: GetFollowingCountParams, 455 ): Promise<GetFollowCountResponse> { 456 return this.request<GetFollowCountResponse>( 457 'GET', 458 `/api/users/${params.identifier}/following/count`, 459 ); 460 } 461 462 async getFollowersCount( 463 params: GetFollowersCountParams, 464 ): Promise<GetFollowCountResponse> { 465 return this.request<GetFollowCountResponse>( 466 'GET', 467 `/api/users/${params.identifier}/followers/count`, 468 ); 469 } 470 471 async getFollowingCollectionsCount( 472 params: GetFollowingCollectionsCountParams, 473 ): Promise<GetFollowCountResponse> { 474 return this.request<GetFollowCountResponse>( 475 'GET', 476 `/api/users/${params.identifier}/following-collections/count`, 477 ); 478 } 479 480 async getCollectionFollowersCount( 481 params: GetCollectionFollowersCountParams, 482 ): Promise<GetFollowCountResponse> { 483 return this.request<GetFollowCountResponse>( 484 'GET', 485 `/api/collections/${params.collectionId}/followers/count`, 486 ); 487 } 488 489 async getCollectionContributors( 490 params: GetCollectionContributorsParams, 491 ): Promise<GetCollectionContributorsResponse> { 492 const searchParams = new URLSearchParams(); 493 if (params.page) searchParams.set('page', params.page.toString()); 494 if (params.limit) searchParams.set('limit', params.limit.toString()); 495 496 const queryString = searchParams.toString(); 497 const endpoint = queryString 498 ? `/api/collections/${params.collectionId}/contributors?${queryString}` 499 : `/api/collections/${params.collectionId}/contributors`; 500 501 return this.request<GetCollectionContributorsResponse>('GET', endpoint); 502 } 503 504 async getConnectionsForUrl( 505 params: GetConnectionsForUrlParams, 506 ): Promise<GetConnectionsForUrlResponse> { 507 const searchParams = new URLSearchParams(); 508 searchParams.set('url', params.url); 509 if (params.direction) searchParams.set('direction', params.direction); 510 if (params.page) searchParams.set('page', params.page.toString()); 511 if (params.limit) searchParams.set('limit', params.limit.toString()); 512 if (params.sortBy) searchParams.set('sortBy', params.sortBy); 513 if (params.sortOrder) searchParams.set('sortOrder', params.sortOrder); 514 if (params.connectionTypes) { 515 searchParams.set('connectionTypes', params.connectionTypes.join(',')); 516 } 517 518 return this.request<GetConnectionsForUrlResponse>( 519 'GET', 520 `/api/connections/url?${searchParams}`, 521 ); 522 } 523 524 async getConnections( 525 params: GetConnectionsParams, 526 ): Promise<GetConnectionsResponse> { 527 const searchParams = new URLSearchParams(); 528 if (params.page) searchParams.set('page', params.page.toString()); 529 if (params.limit) searchParams.set('limit', params.limit.toString()); 530 if (params.sortBy) searchParams.set('sortBy', params.sortBy); 531 if (params.sortOrder) searchParams.set('sortOrder', params.sortOrder); 532 if (params.connectionTypes) { 533 searchParams.set('connectionTypes', params.connectionTypes.join(',')); 534 } 535 536 const queryString = searchParams.toString(); 537 const endpoint = queryString 538 ? `/api/connections/user/${params.identifier}?${queryString}` 539 : `/api/connections/user/${params.identifier}`; 540 541 return this.request<GetConnectionsResponse>('GET', endpoint); 542 } 543 544 async searchUrls(params: SearchUrlsParams): Promise<SearchUrlsResponse> { 545 const searchParams = new URLSearchParams(); 546 searchParams.set('searchQuery', params.searchQuery); 547 if (params.page) searchParams.set('page', params.page.toString()); 548 if (params.limit) searchParams.set('limit', params.limit.toString()); 549 if (params.sortBy) searchParams.set('sortBy', params.sortBy); 550 if (params.sortOrder) searchParams.set('sortOrder', params.sortOrder); 551 if (params.urlType) searchParams.set('urlType', params.urlType); 552 553 return this.request<SearchUrlsResponse>( 554 'GET', 555 `/api/cards/search?${searchParams}`, 556 ); 557 } 558 559 async getUserGraphData(params: { 560 identifier: string; 561 page?: number; 562 limit?: number; 563 }): Promise<GetGraphDataResponse> { 564 // Build query string with pagination parameters 565 const searchParams = new URLSearchParams(); 566 if (params?.page) searchParams.set('page', params.page.toString()); 567 if (params?.limit) searchParams.set('limit', params.limit.toString()); 568 569 const queryString = searchParams.toString(); 570 const endpoint = queryString 571 ? `/api/graph/user/${params.identifier}?${queryString}` 572 : `/api/graph/user/${params.identifier}`; 573 574 return this.request<GetGraphDataResponse>('GET', endpoint); 575 } 576 577 async getUrlGraphData( 578 params: GetUrlGraphDataParams, 579 ): Promise<GetGraphDataResponse> { 580 // Build query string with url and depth parameters 581 const searchParams = new URLSearchParams(); 582 searchParams.set('url', params.url); 583 if (params.depth) searchParams.set('depth', params.depth.toString()); 584 585 const endpoint = `/api/graph/url?${searchParams.toString()}`; 586 587 return this.request<GetGraphDataResponse>('GET', endpoint); 588 } 589 590 async getGraphData( 591 params?: GetGraphDataParams, 592 ): Promise<GetGraphDataResponse> { 593 // Check if mock data should be used (for performance testing) 594 // Set NEXT_PUBLIC_USE_MOCK_GRAPH_DATA=true in .env.local to enable 595 const useMockData = process.env.NEXT_PUBLIC_USE_MOCK_GRAPH_DATA === 'true'; 596 // const useMockData = true; 597 598 if (useMockData) { 599 const { generateMockGraphData, MOCK_GRAPH_PRESETS } = await import( 600 './mockGraphData' 601 ); 602 603 // You can change the preset here for different test scenarios 604 // Options: small, medium, large, extraLarge, denseSmall 605 const mockData = generateMockGraphData(MOCK_GRAPH_PRESETS.large); 606 607 // Simulate network delay for realistic testing 608 await new Promise((resolve) => setTimeout(resolve, 500)); 609 610 // Apply pagination to mock data 611 const page = params?.page || 1; 612 const limit = params?.limit || 300; 613 const offset = (page - 1) * limit; 614 const totalCount = mockData.nodes.length; 615 const totalPages = Math.ceil(totalCount / limit); 616 const hasMore = page < totalPages; 617 618 const paginatedNodes = mockData.nodes.slice(offset, offset + limit); 619 const loadedNodeIds = new Set(paginatedNodes.map((n) => n.id)); 620 const filteredEdges = mockData.edges.filter( 621 (e) => loadedNodeIds.has(e.source) && loadedNodeIds.has(e.target), 622 ); 623 624 return { 625 nodes: paginatedNodes, 626 edges: filteredEdges, 627 pagination: { 628 currentPage: page, 629 totalPages, 630 totalCount, 631 hasMore, 632 limit, 633 }, 634 }; 635 } 636 637 // Build query string with pagination parameters 638 const searchParams = new URLSearchParams(); 639 if (params?.page) searchParams.set('page', params.page.toString()); 640 if (params?.limit) searchParams.set('limit', params.limit.toString()); 641 642 const queryString = searchParams.toString(); 643 const endpoint = queryString 644 ? `/api/graph/data?${queryString}` 645 : '/api/graph/data'; 646 647 return this.request<GetGraphDataResponse>('GET', endpoint); 648 } 649}