@@ -19,6 +19,7 @@ limitations under the License.
1919*/
2020
2121import { kgUrl , kgDefaultStage } from "./globals" ;
22+ import { mergeItems } from "./utility" ;
2223//import examplePatchClampData from "./example_data/example_patch_clamp_dataset.json";
2324
2425function isEmpty ( obj ) {
@@ -73,11 +74,24 @@ async function queryKG(kgQuery, searchParams, auth) {
7374async function getKGItem ( cacheLabel , kgQuery , instanceId , auth , stage = kgDefaultStage ) {
7475 console . log ( "getKGItem " + cacheLabel + instanceId ) ;
7576 if ( ! cache [ cacheLabel ] [ instanceId ] ) {
76- const searchParams = { stage : stage , instanceId : instanceId } ;
77- const result = await queryKG ( kgQuery , searchParams , auth ) ;
78- if ( result ) {
79- const items = result . data ;
80- cache [ cacheLabel ] [ instanceId ] = items [ 0 ] ;
77+ if ( Array . isArray ( stage ) ) {
78+ // Curators pass stage as an array (e.g. ["IN_PROGRESS", "RELEASED"]) so that
79+ // we can fetch the same item under both stages in parallel and merge the results.
80+ // This is necessary because IN_PROGRESS sometimes returns less complete data
81+ // than RELEASED — for example, nested arrays that are empty in IN_PROGRESS but
82+ // populated in RELEASED. mergeItems fills those gaps while keeping IN_PROGRESS
83+ // values wherever they are present, so curators see the union of both.
84+ const results = await Promise . all (
85+ stage . map ( ( s ) => queryKG ( kgQuery , { stage : s , instanceId } , auth ) )
86+ ) ;
87+ const items = results . map ( ( r ) => r ?. data ?. [ 0 ] ) ;
88+ cache [ cacheLabel ] [ instanceId ] = mergeItems ( items [ 0 ] , items [ 1 ] ) ;
89+ } else {
90+ const searchParams = { stage : stage , instanceId : instanceId } ;
91+ const result = await queryKG ( kgQuery , searchParams , auth ) ;
92+ if ( result ) {
93+ cache [ cacheLabel ] [ instanceId ] = result . data [ 0 ] ;
94+ }
8195 }
8296 }
8397 return cache [ cacheLabel ] [ instanceId ] ;
@@ -96,20 +110,36 @@ async function getKGData(
96110 if ( isEmpty ( cache [ cacheLabel ] ) ) {
97111 // if the cache is empty we need to fill it
98112 console . log ( kgUrl ) ;
99- let searchParams = {
100- returnTotalResults : true ,
101- stage : stage ,
102- size : size ,
103- from : from ,
104- } ;
105- if ( searchFilters ) {
106- searchParams = { ...searchParams , searchFilters } ;
107- }
108- const result = await queryKG ( kgQuery , searchParams , auth ) ;
109- if ( result ) {
110- const items = result . data ;
111- for ( const index in items ) {
112- cache [ cacheLabel ] [ items [ index ] . id ] = items [ index ] ;
113+ if ( Array . isArray ( stage ) ) {
114+ const fetchForStage = async ( s ) => {
115+ let searchParams = { returnTotalResults : true , stage : s , size, from } ;
116+ if ( searchFilters ) searchParams = { ...searchParams , searchFilters } ;
117+ const result = await queryKG ( kgQuery , searchParams , auth ) ;
118+ return result ? result . data : [ ] ;
119+ } ;
120+ const [ primaryItems , fallbackItems ] = await Promise . all ( stage . map ( fetchForStage ) ) ;
121+ const primaryById = Object . fromEntries ( primaryItems . map ( ( i ) => [ i . id , i ] ) ) ;
122+ const fallbackById = Object . fromEntries ( fallbackItems . map ( ( i ) => [ i . id , i ] ) ) ;
123+ const allIds = new Set ( [ ...Object . keys ( primaryById ) , ...Object . keys ( fallbackById ) ] ) ;
124+ for ( const id of allIds ) {
125+ cache [ cacheLabel ] [ id ] = mergeItems ( primaryById [ id ] , fallbackById [ id ] ) ;
126+ }
127+ } else {
128+ let searchParams = {
129+ returnTotalResults : true ,
130+ stage : stage ,
131+ size : size ,
132+ from : from ,
133+ } ;
134+ if ( searchFilters ) {
135+ searchParams = { ...searchParams , searchFilters } ;
136+ }
137+ const result = await queryKG ( kgQuery , searchParams , auth ) ;
138+ if ( result ) {
139+ const items = result . data ;
140+ for ( const index in items ) {
141+ cache [ cacheLabel ] [ items [ index ] . id ] = items [ index ] ;
142+ }
113143 }
114144 }
115145 }
0 commit comments