@@ -129,6 +129,7 @@ export default class GraphQLComponent<TContextType extends ComponentContext = Co
129129 _dataSourceContextInject : DataSourceInjectionFunction ;
130130 _transforms : SchemaMapper [ ]
131131 private _transformedSchema : GraphQLSchema ;
132+ private _middleware : MiddlewareEntry [ ] = [ ] ;
132133
133134 constructor ( {
134135 types,
@@ -180,27 +181,39 @@ export default class GraphQLComponent<TContextType extends ComponentContext = Co
180181 }
181182 } ) : [ ] ;
182183
183-
184184 this . _context = async ( globalContext : Record < string , unknown > ) : Promise < TContextType > => {
185- //TODO: currently the context injected into data sources won't have data sources on it
185+ //BREAKING: The context injected into data sources won't have data sources on it
186186 const ctx = {
187187 dataSources : this . _dataSourceContextInject ( globalContext )
188188 } ;
189189
190- for ( const { component } of this . imports ) {
191- const { dataSources, ...importedContext } = await component . context ( globalContext ) ;
192- Object . assign ( ctx . dataSources , dataSources ) ;
193- Object . assign ( ctx , importedContext ) ;
190+ // Only process imports if they exist
191+ if ( this . _imports . length > 0 ) {
192+ // Process imports in parallel if they're independent
193+ const importPromises = this . _imports . map ( async ( { component } ) => {
194+ const importContext = await component . context ( globalContext ) ;
195+ return importContext ;
196+ } ) ;
197+
198+ const importResults = await Promise . all ( importPromises ) ;
199+
200+ // Merge results efficiently
201+ for ( const { dataSources, ...importedContext } of importResults ) {
202+ Object . assign ( ctx . dataSources , dataSources ) ;
203+ Object . assign ( ctx , importedContext ) ;
204+ }
194205 }
195206
207+ // Handle namespace context if present
196208 if ( context ) {
197209 debug ( `building ${ context . namespace } context` ) ;
198210
199211 if ( ! ctx [ context . namespace ] ) {
200212 ctx [ context . namespace ] = { } ;
201213 }
202214
203- Object . assign ( ctx [ context . namespace ] , await context . factory . call ( this , globalContext ) ) ;
215+ const namespaceContext = await context . factory . call ( this , globalContext ) ;
216+ Object . assign ( ctx [ context . namespace ] , namespaceContext ) ;
204217 }
205218
206219 return ctx as TContextType ;
@@ -211,43 +224,42 @@ export default class GraphQLComponent<TContextType extends ComponentContext = Co
211224 }
212225
213226 get context ( ) : IContextWrapper {
214-
227+ // Cache middleware array to avoid recreation
215228 const contextFn = async ( context : Record < string , unknown > ) : Promise < ComponentContext > => {
216229 debug ( `building root context` ) ;
217230
218- const middleware : MiddlewareEntry [ ] = ( contextFn as any ) . _middleware || [ ] ;
231+ let processedContext = context ;
219232
220- for ( const { name, fn } of middleware ) {
221- debug ( `applying ${ name } middleware` ) ;
222- context = await fn ( context ) ;
233+ // Apply middleware more efficiently
234+ if ( this . _middleware . length > 0 ) {
235+ for ( const { name, fn } of this . _middleware ) {
236+ debug ( `applying ${ name } middleware` ) ;
237+ processedContext = await fn ( processedContext ) ;
238+ }
223239 }
224240
225- const componentContext = await this . _context ( context ) ;
226-
227- const globalContext = {
228- ...context ,
229- ...componentContext
230- } ;
241+ const componentContext = await this . _context ( processedContext ) ;
231242
232- return globalContext ;
243+ // More efficient object composition
244+ return Object . assign ( { } , processedContext , componentContext ) ;
233245 } ;
234246
235- contextFn . _middleware = [ ] ;
236-
237- contextFn . use = function ( name : string , fn : ContextFunction ) : IContextWrapper {
247+ contextFn . use = ( name : string | ContextFunction , fn ?: ContextFunction ) : IContextWrapper => {
238248 if ( typeof name === 'function' ) {
239249 fn = name ;
240250 name = 'unknown' ;
241251 }
242252 debug ( `adding ${ name } middleware` ) ;
243- contextFn . _middleware . push ( { name, fn } ) ;
253+ this . _middleware . push ( { name : name as string , fn : fn ! } ) ;
244254
245255 return contextFn ;
246256 } ;
247257
248258 return contextFn ;
249259 }
250260
261+
262+
251263 get name ( ) : string {
252264 return this . constructor . name ;
253265 }
@@ -374,8 +386,8 @@ export default class GraphQLComponent<TContextType extends ComponentContext = Co
374386 for ( const [ key , fn ] of Object . entries ( transform ) ) {
375387 if ( ! mapping [ key ] ) {
376388 functions [ key ] = [ ] ;
377- let result = undefined ;
378389 mapping [ key ] = function ( ...args ) {
390+ let result ;
379391 while ( functions [ key ] . length ) {
380392 const mapper = functions [ key ] . shift ( ) ;
381393 result = mapper ( ...args ) ;
0 commit comments