From 4877a7d4803016802103ea95b60a481f62c03ccc Mon Sep 17 00:00:00 2001 From: Shashank Budhanuru Ramaraju Date: Thu, 27 Nov 2025 11:37:24 +0000 Subject: [PATCH 1/3] fetch features by ids --- packages/apollo-cli/README.md | 2 +- .../apollo-cli/src/commands/feature/get.ts | 4 +++- .../src/entity/gff3Object.dto.ts | 5 ++++ .../src/features/features.controller.ts | 24 +++++++++++++++---- .../src/features/features.service.ts | 20 ++++++++++++++++ .../CollaborationServerDriver.ts | 2 +- 6 files changed, 50 insertions(+), 7 deletions(-) diff --git a/packages/apollo-cli/README.md b/packages/apollo-cli/README.md index 909680bb4..541157565 100644 --- a/packages/apollo-cli/README.md +++ b/packages/apollo-cli/README.md @@ -16,7 +16,7 @@ $ npm install -g @apollo-annotation/cli $ apollo COMMAND running command... $ apollo (--version) -@apollo-annotation/cli/0.3.9 linux-x64 node-v24.6.0 +@apollo-annotation/cli/0.3.9 darwin-x64 node-v20.19.0 $ apollo --help [COMMAND] USAGE $ apollo COMMAND diff --git a/packages/apollo-cli/src/commands/feature/get.ts b/packages/apollo-cli/src/commands/feature/get.ts index 7ac1af571..16f95108e 100644 --- a/packages/apollo-cli/src/commands/feature/get.ts +++ b/packages/apollo-cli/src/commands/feature/get.ts @@ -86,7 +86,9 @@ export default class Get extends BaseCommand { start: number, end: number, ): Promise { - const url = new URL(localhostToAddress(`${address}/features/getFeatures`)) + const url = new URL( + localhostToAddress(`${address}/features/getFeaturesByRange`), + ) const searchParams = new URLSearchParams({ refSeq, start: start.toString(), diff --git a/packages/apollo-collaboration-server/src/entity/gff3Object.dto.ts b/packages/apollo-collaboration-server/src/entity/gff3Object.dto.ts index f4502e253..dac43ccfb 100644 --- a/packages/apollo-collaboration-server/src/entity/gff3Object.dto.ts +++ b/packages/apollo-collaboration-server/src/entity/gff3Object.dto.ts @@ -28,3 +28,8 @@ export interface FeatureRangeSearchDto { start: number end: number } + +export interface FeatureIdsSearchDto { + featureIds: string[] + topLevel?: boolean +} diff --git a/packages/apollo-collaboration-server/src/features/features.controller.ts b/packages/apollo-collaboration-server/src/features/features.controller.ts index df5fd97e8..054282879 100644 --- a/packages/apollo-collaboration-server/src/features/features.controller.ts +++ b/packages/apollo-collaboration-server/src/features/features.controller.ts @@ -1,13 +1,18 @@ import { + Body, Controller, Get, Logger, Param, ParseBoolPipe, + Post, Query, } from '@nestjs/common' -import { FeatureRangeSearchDto } from '../entity/gff3Object.dto' +import { + FeatureIdsSearchDto, + FeatureRangeSearchDto, +} from '../entity/gff3Object.dto' import { Role } from '../utils/role/role.enum' import { Validations } from '../utils/validation/validatation.decorator' @@ -36,15 +41,26 @@ export class FeaturesController { * @returns Return 'HttpStatus.OK' and array of features if search was successful * or if search data was not found or in case of error throw exception */ - @Get('getFeatures') - getFeatures(@Query() request: FeatureRangeSearchDto) { + @Get('getFeaturesByRange') + getFeaturesByRange(@Query() request: FeatureRangeSearchDto) { this.logger.debug( - `getFeaturesByCriteria -method: refSeq: ${request.refSeq}, start: ${request.start}, end: ${request.end}`, + `getFeaturesByRange -method: refSeq: ${request.refSeq}, start: ${request.start}, end: ${request.end}`, ) return this.featuresService.findByRange(request) } + @Post('getFeatures') + getFeatures(@Body() request: FeatureIdsSearchDto) { + this.logger.debug( + `getFeatures -method: featureIds: ${JSON.stringify(request.featureIds)}`, + ) + return this.featuresService.findByFeatureIds( + request.featureIds, + request.topLevel, + ) + } + @Get('count') async getFeatureCount(@Query() featureCountRequest: FeatureCountRequest) { this.logger.debug( diff --git a/packages/apollo-collaboration-server/src/features/features.service.ts b/packages/apollo-collaboration-server/src/features/features.service.ts index 21cc0054d..a2c99a2a2 100644 --- a/packages/apollo-collaboration-server/src/features/features.service.ts +++ b/packages/apollo-collaboration-server/src/features/features.service.ts @@ -117,6 +117,26 @@ export class FeaturesService { return } + async findByFeatureIds(featureIds: string[], topLevel?: boolean) { + const foundFeatures: Feature[] = [] + // all featureIds that have already been fetched + const fetchedFeatureIds = new Set() + + for (const featureId of featureIds) { + if (fetchedFeatureIds.has(featureId)) { + this.logger.debug(`FeatureId ${featureId} already fetched, skipping...`) + continue + } + const feature = await this.findById(featureId, topLevel) + foundFeatures.push(feature) + + for (const id of feature.allIds) { + fetchedFeatureIds.add(id) + } + } + return foundFeatures + } + /** * Get feature by featureId. When retrieving features by id, the features and any of its children are returned, but not any of its parent or sibling features. * @param featureId - featureId diff --git a/packages/jbrowse-plugin-apollo/src/BackendDrivers/CollaborationServerDriver.ts b/packages/jbrowse-plugin-apollo/src/BackendDrivers/CollaborationServerDriver.ts index 5650ea97b..242f51425 100644 --- a/packages/jbrowse-plugin-apollo/src/BackendDrivers/CollaborationServerDriver.ts +++ b/packages/jbrowse-plugin-apollo/src/BackendDrivers/CollaborationServerDriver.ts @@ -119,7 +119,7 @@ export class CollaborationServerDriver extends BackendDriver { ) as ApolloInternetAccount const { baseURL } = internetAccount - const url = new URL('features/getFeatures', baseURL) + const url = new URL('features/getFeaturesByRange', baseURL) const searchParams = new URLSearchParams({ refSeq, start: String(start), From fd1e2fe6989673a7e1182fe4d3a9e813d33699a6 Mon Sep 17 00:00:00 2001 From: Shashank Budhanuru Ramaraju Date: Thu, 27 Nov 2025 13:19:21 +0000 Subject: [PATCH 2/3] handle exceptions --- .../src/features/features.service.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/apollo-collaboration-server/src/features/features.service.ts b/packages/apollo-collaboration-server/src/features/features.service.ts index a2c99a2a2..87f078048 100644 --- a/packages/apollo-collaboration-server/src/features/features.service.ts +++ b/packages/apollo-collaboration-server/src/features/features.service.ts @@ -127,11 +127,18 @@ export class FeaturesService { this.logger.debug(`FeatureId ${featureId} already fetched, skipping...`) continue } - const feature = await this.findById(featureId, topLevel) - foundFeatures.push(feature) - for (const id of feature.allIds) { - fetchedFeatureIds.add(id) + try { + const feature = await this.findById(featureId, topLevel) + foundFeatures.push(feature) + for (const id of feature.allIds) { + fetchedFeatureIds.add(id) + } + } catch (error) { + this.logger.error( + `Error occurred while fetching feature ${featureId}`, + error instanceof Error ? error.stack : String(error), + ) } } return foundFeatures From 1933f48357a77918bbd1274c9243dd9739864897 Mon Sep 17 00:00:00 2001 From: Garrett Stevens Date: Tue, 9 Dec 2025 18:23:44 +0000 Subject: [PATCH 3/3] Standardize naming --- packages/apollo-cli/README.md | 2 +- packages/apollo-cli/src/commands/feature/get.ts | 4 +--- .../src/features/features.controller.ts | 12 +++++------- .../src/BackendDrivers/CollaborationServerDriver.ts | 2 +- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/packages/apollo-cli/README.md b/packages/apollo-cli/README.md index 541157565..909680bb4 100644 --- a/packages/apollo-cli/README.md +++ b/packages/apollo-cli/README.md @@ -16,7 +16,7 @@ $ npm install -g @apollo-annotation/cli $ apollo COMMAND running command... $ apollo (--version) -@apollo-annotation/cli/0.3.9 darwin-x64 node-v20.19.0 +@apollo-annotation/cli/0.3.9 linux-x64 node-v24.6.0 $ apollo --help [COMMAND] USAGE $ apollo COMMAND diff --git a/packages/apollo-cli/src/commands/feature/get.ts b/packages/apollo-cli/src/commands/feature/get.ts index 16f95108e..7ac1af571 100644 --- a/packages/apollo-cli/src/commands/feature/get.ts +++ b/packages/apollo-cli/src/commands/feature/get.ts @@ -86,9 +86,7 @@ export default class Get extends BaseCommand { start: number, end: number, ): Promise { - const url = new URL( - localhostToAddress(`${address}/features/getFeaturesByRange`), - ) + const url = new URL(localhostToAddress(`${address}/features/getFeatures`)) const searchParams = new URLSearchParams({ refSeq, start: start.toString(), diff --git a/packages/apollo-collaboration-server/src/features/features.controller.ts b/packages/apollo-collaboration-server/src/features/features.controller.ts index 054282879..22006282f 100644 --- a/packages/apollo-collaboration-server/src/features/features.controller.ts +++ b/packages/apollo-collaboration-server/src/features/features.controller.ts @@ -41,20 +41,18 @@ export class FeaturesController { * @returns Return 'HttpStatus.OK' and array of features if search was successful * or if search data was not found or in case of error throw exception */ - @Get('getFeaturesByRange') + @Get('getFeatures') getFeaturesByRange(@Query() request: FeatureRangeSearchDto) { this.logger.debug( - `getFeaturesByRange -method: refSeq: ${request.refSeq}, start: ${request.start}, end: ${request.end}`, + `getFeatures endpoint: refSeq: ${request.refSeq}, start: ${request.start}, end: ${request.end}`, ) return this.featuresService.findByRange(request) } - @Post('getFeatures') - getFeatures(@Body() request: FeatureIdsSearchDto) { - this.logger.debug( - `getFeatures -method: featureIds: ${JSON.stringify(request.featureIds)}`, - ) + @Post('getByIds') + findByFeatureIds(@Body() request: FeatureIdsSearchDto) { + this.logger.debug(`: featureIds: ${JSON.stringify(request.featureIds)}`) return this.featuresService.findByFeatureIds( request.featureIds, request.topLevel, diff --git a/packages/jbrowse-plugin-apollo/src/BackendDrivers/CollaborationServerDriver.ts b/packages/jbrowse-plugin-apollo/src/BackendDrivers/CollaborationServerDriver.ts index 242f51425..5650ea97b 100644 --- a/packages/jbrowse-plugin-apollo/src/BackendDrivers/CollaborationServerDriver.ts +++ b/packages/jbrowse-plugin-apollo/src/BackendDrivers/CollaborationServerDriver.ts @@ -119,7 +119,7 @@ export class CollaborationServerDriver extends BackendDriver { ) as ApolloInternetAccount const { baseURL } = internetAccount - const url = new URL('features/getFeaturesByRange', baseURL) + const url = new URL('features/getFeatures', baseURL) const searchParams = new URLSearchParams({ refSeq, start: String(start),