@@ -7,9 +7,10 @@ import version from './version';
77import createHelpers from './createHelpers' ;
88import {
99 createDocumentationMessageGenerator ,
10- noop ,
10+ findIndex ,
1111 isPlainObject ,
1212 mergeDeep ,
13+ noop ,
1314} from './utils' ;
1415
1516const withUsage = createDocumentationMessageGenerator ( {
@@ -440,7 +441,46 @@ export function enhanceConfiguration(configuration, widgetDefinition) {
440441 // Get the relevant partial configuration asked by the widget
441442 const partialConfiguration = widgetDefinition . getConfiguration ( configuration ) ;
442443
443- return mergeDeep ( configuration , partialConfiguration ) ;
444+ if ( ! partialConfiguration ) {
445+ return configuration ;
446+ }
447+
448+ if ( ! partialConfiguration . hierarchicalFacets ) {
449+ return mergeDeep ( configuration , partialConfiguration ) ;
450+ }
451+
452+ const {
453+ hierarchicalFacets,
454+ ...partialWithoutHierarchcialFacets
455+ } = partialConfiguration ;
456+
457+ // The `mergeDeep` function uses a `uniq` function under the hood, but the
458+ // implementation does not support arrays of objects (we also had the issue
459+ // with the Lodash version). The `hierarchicalFacets` attribute is an array
460+ // of objects, which means that this attribute is never deduplicated. It
461+ // becomes problematic when widgets are frequently added/removed, since the
462+ // function `enhanceConfiguration` is called at each operation.
463+ // https://github.com/algolia/instantsearch.js/issues/3278
464+ const configurationWithHierarchicalFacets = {
465+ ...configuration ,
466+ hierarchicalFacets : hierarchicalFacets . reduce ( ( facets , facet ) => {
467+ const index = findIndex ( facets , _ => _ . name === facet . name ) ;
468+
469+ if ( index === - 1 ) {
470+ return facets . concat ( facet ) ;
471+ }
472+
473+ const nextFacets = facets . slice ( ) ;
474+ nextFacets . splice ( index , 1 , facet ) ;
475+
476+ return nextFacets ;
477+ } , configuration . hierarchicalFacets || [ ] ) ,
478+ } ;
479+
480+ return mergeDeep (
481+ configurationWithHierarchicalFacets ,
482+ partialWithoutHierarchcialFacets
483+ ) ;
444484}
445485
446486export default InstantSearch ;
0 commit comments