instantsearch.js 4.79.2 → 4.80.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -66,7 +66,7 @@ var RawHtml = /*#__PURE__*/function (_Component) {
66
66
  });
67
67
  // if there is one TextNode first and one TextNode last, the
68
68
  // last one's nodeValue will be assigned to the first.
69
- if (this.nodes[0].nodeValue) {
69
+ if (this.nodes[0] && this.nodes[0].nodeValue) {
70
70
  this.nodes[0].nodeValue = '';
71
71
  }
72
72
  }
@@ -329,12 +329,9 @@ var InstantSearch = /*#__PURE__*/function (_EventEmitter) {
329
329
  if (!Array.isArray(widgets)) {
330
330
  throw new Error(withUsage('The `addWidgets` method expects an array of widgets. Please use `addWidget`.'));
331
331
  }
332
- if (widgets.some(function (widget) {
333
- return typeof widget.init !== 'function' && typeof widget.render !== 'function';
332
+ if (this.compositionID && widgets.some(function (w) {
333
+ return !Array.isArray(w) && (0, _utils.isIndexWidget)(w) && !w._isolated;
334
334
  })) {
335
- throw new Error(withUsage('The widget definition expects a `render` and/or an `init` method.'));
336
- }
337
- if (this.compositionID && widgets.some(_utils.isIndexWidget)) {
338
335
  throw new Error(withUsage('The `index` widget cannot be used with a composition-based InstantSearch implementation.'));
339
336
  }
340
337
  this.mainIndex.addWidgets(widgets);
@@ -367,11 +364,6 @@ var InstantSearch = /*#__PURE__*/function (_EventEmitter) {
367
364
  if (!Array.isArray(widgets)) {
368
365
  throw new Error(withUsage('The `removeWidgets` method expects an array of widgets. Please use `removeWidget`.'));
369
366
  }
370
- if (widgets.some(function (widget) {
371
- return typeof widget.dispose !== 'function';
372
- })) {
373
- throw new Error(withUsage('The widget definition expects a `dispose` method.'));
374
- }
375
367
  this.mainIndex.removeWidgets(widgets);
376
368
  return this;
377
369
  }
@@ -4,4 +4,4 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _default = exports.default = '4.79.2';
7
+ var _default = exports.default = '4.80.0';
@@ -117,12 +117,18 @@ function resolveScopedResultsFromWidgets(widgets) {
117
117
  }, []);
118
118
  }
119
119
  var index = function index(widgetParams) {
120
- if (widgetParams === undefined || widgetParams.indexName === undefined) {
120
+ if (widgetParams === undefined || widgetParams.indexName === undefined && !widgetParams.EXPERIMENTAL_isolated) {
121
121
  throw new Error(withUsage('The `indexName` option is required.'));
122
122
  }
123
- var indexName = widgetParams.indexName,
123
+
124
+ // When isolated=true, we use an empty string as the default indexName.
125
+ // This is intentional: isolated indices do not require a real index name.
126
+ var _widgetParams$indexNa = widgetParams.indexName,
127
+ indexName = _widgetParams$indexNa === void 0 ? '' : _widgetParams$indexNa,
124
128
  _widgetParams$indexId = widgetParams.indexId,
125
- indexId = _widgetParams$indexId === void 0 ? indexName : _widgetParams$indexId;
129
+ indexId = _widgetParams$indexId === void 0 ? indexName : _widgetParams$indexId,
130
+ _widgetParams$EXPERIM = widgetParams.EXPERIMENTAL_isolated,
131
+ isolated = _widgetParams$EXPERIM === void 0 ? false : _widgetParams$EXPERIM;
126
132
  var localWidgets = [];
127
133
  var localUiState = {};
128
134
  var localInstantSearchInstance = null;
@@ -135,6 +141,7 @@ var index = function index(widgetParams) {
135
141
  return {
136
142
  $$type: 'ais.index',
137
143
  $$widgetType: 'ais.index',
144
+ _isolated: isolated,
138
145
  getIndexName: function getIndexName() {
139
146
  return indexName;
140
147
  },
@@ -186,7 +193,7 @@ var index = function index(widgetParams) {
186
193
  return resolveScopedResultsFromWidgets(widgetSiblings);
187
194
  },
188
195
  getParent: function getParent() {
189
- return localParent;
196
+ return isolated ? null : localParent;
190
197
  },
191
198
  createURL: function createURL(nextState) {
192
199
  if (typeof nextState === 'function') {
@@ -205,12 +212,15 @@ var index = function index(widgetParams) {
205
212
  if (!Array.isArray(widgets)) {
206
213
  throw new Error(withUsage('The `addWidgets` method expects an array of widgets.'));
207
214
  }
208
- if (widgets.some(function (widget) {
215
+ var flatWidgets = widgets.reduce(function (acc, w) {
216
+ return acc.concat(Array.isArray(w) ? w : [w]);
217
+ }, []);
218
+ if (flatWidgets.some(function (widget) {
209
219
  return typeof widget.init !== 'function' && typeof widget.render !== 'function';
210
220
  })) {
211
221
  throw new Error(withUsage('The widget definition expects a `render` and/or an `init` method.'));
212
222
  }
213
- widgets.forEach(function (widget) {
223
+ flatWidgets.forEach(function (widget) {
214
224
  if ((0, _utils.isIndexWidget)(widget)) {
215
225
  return;
216
226
  }
@@ -225,8 +235,8 @@ var index = function index(widgetParams) {
225
235
  }
226
236
  (0, _addWidgetId.addWidgetId)(widget);
227
237
  });
228
- localWidgets = localWidgets.concat(widgets);
229
- if (localInstantSearchInstance && Boolean(widgets.length)) {
238
+ localWidgets = localWidgets.concat(flatWidgets);
239
+ if (localInstantSearchInstance && Boolean(flatWidgets.length)) {
230
240
  privateHelperSetState(helper, {
231
241
  state: getLocalWidgetsSearchParameters(localWidgets, {
232
242
  uiState: localUiState,
@@ -242,7 +252,7 @@ var index = function index(widgetParams) {
242
252
  // We compute the render state before calling `init` in a separate loop
243
253
  // to construct the whole render state object that is then passed to
244
254
  // `init`.
245
- widgets.forEach(function (widget) {
255
+ flatWidgets.forEach(function (widget) {
246
256
  if (widget.getRenderState) {
247
257
  var renderState = widget.getRenderState(localInstantSearchInstance.renderState[_this.getIndexId()] || {}, (0, _utils.createInitArgs)(localInstantSearchInstance, _this, localInstantSearchInstance._initialUiState));
248
258
  storeRenderState({
@@ -252,12 +262,17 @@ var index = function index(widgetParams) {
252
262
  });
253
263
  }
254
264
  });
255
- widgets.forEach(function (widget) {
265
+ flatWidgets.forEach(function (widget) {
256
266
  if (widget.init) {
257
267
  widget.init((0, _utils.createInitArgs)(localInstantSearchInstance, _this, localInstantSearchInstance._initialUiState));
258
268
  }
259
269
  });
260
- localInstantSearchInstance.scheduleSearch();
270
+ if (isolated) {
271
+ var _helper2;
272
+ (_helper2 = helper) === null || _helper2 === void 0 ? void 0 : _helper2.search();
273
+ } else {
274
+ localInstantSearchInstance.scheduleSearch();
275
+ }
261
276
  }
262
277
  return this;
263
278
  },
@@ -266,13 +281,16 @@ var index = function index(widgetParams) {
266
281
  if (!Array.isArray(widgets)) {
267
282
  throw new Error(withUsage('The `removeWidgets` method expects an array of widgets.'));
268
283
  }
269
- if (widgets.some(function (widget) {
284
+ var flatWidgets = widgets.reduce(function (acc, w) {
285
+ return acc.concat(Array.isArray(w) ? w : [w]);
286
+ }, []);
287
+ if (flatWidgets.some(function (widget) {
270
288
  return typeof widget.dispose !== 'function';
271
289
  })) {
272
290
  throw new Error(withUsage('The widget definition expects a `dispose` method.'));
273
291
  }
274
292
  localWidgets = localWidgets.filter(function (widget) {
275
- return widgets.indexOf(widget) === -1;
293
+ return flatWidgets.indexOf(widget) === -1;
276
294
  });
277
295
  localWidgets.forEach(function (widget) {
278
296
  if ((0, _utils.isIndexWidget)(widget)) {
@@ -288,8 +306,8 @@ var index = function index(widgetParams) {
288
306
  hasSearchWidget = true;
289
307
  }
290
308
  });
291
- if (localInstantSearchInstance && Boolean(widgets.length)) {
292
- var _widgets$reduce = widgets.reduce(function (states, widget) {
309
+ if (localInstantSearchInstance && Boolean(flatWidgets.length)) {
310
+ var _flatWidgets$reduce = flatWidgets.reduce(function (states, widget) {
293
311
  // the `dispose` method exists at this point we already assert it
294
312
  var next = widget.dispose({
295
313
  helper: helper,
@@ -307,8 +325,8 @@ var index = function index(widgetParams) {
307
325
  cleanedSearchState: helper.state,
308
326
  cleanedRecommendState: helper.recommendState
309
327
  }),
310
- cleanedSearchState = _widgets$reduce.cleanedSearchState,
311
- cleanedRecommendState = _widgets$reduce.cleanedRecommendState;
328
+ cleanedSearchState = _flatWidgets$reduce.cleanedSearchState,
329
+ cleanedRecommendState = _flatWidgets$reduce.cleanedRecommendState;
312
330
  var newState = localInstantSearchInstance.future.preserveSharedStateOnUnmount ? getLocalWidgetsSearchParameters(localWidgets, {
313
331
  uiState: localUiState,
314
332
  initialSearchParameters: new _algoliasearchHelper.default.SearchParameters({
@@ -328,7 +346,12 @@ var index = function index(widgetParams) {
328
346
  helper.setState(newState);
329
347
  helper.recommendState = cleanedRecommendState;
330
348
  if (localWidgets.length) {
331
- localInstantSearchInstance.scheduleSearch();
349
+ if (isolated) {
350
+ var _helper3;
351
+ (_helper3 = helper) === null || _helper3 === void 0 ? void 0 : _helper3.search();
352
+ } else {
353
+ localInstantSearchInstance.scheduleSearch();
354
+ }
332
355
  }
333
356
  }
334
357
  return this;
@@ -366,13 +389,20 @@ var index = function index(widgetParams) {
366
389
  // This Helper is only used for state management we do not care about the
367
390
  // `searchClient`. Only the "main" Helper created at the `InstantSearch`
368
391
  // level is aware of the client.
369
- helper = (0, _algoliasearchHelper.default)({}, parameters.index, parameters);
392
+ helper = (0, _algoliasearchHelper.default)(mainHelper.getClient(), parameters.index, parameters);
370
393
  helper.recommendState = recommendParameters;
371
394
 
372
395
  // We forward the call to `search` to the "main" instance of the Helper
373
396
  // which is responsible for managing the queries (it's the only one that is
374
397
  // aware of the `searchClient`).
375
398
  helper.search = function () {
399
+ if (isolated) {
400
+ instantSearchInstance.status = 'loading';
401
+ _this3.render({
402
+ instantSearchInstance: instantSearchInstance
403
+ });
404
+ return instantSearchInstance.compositionID ? helper.searchWithComposition() : helper.searchOnlyWithDerivedHelpers();
405
+ }
376
406
  if (instantSearchInstance.onStateChange) {
377
407
  instantSearchInstance.onStateChange({
378
408
  uiState: instantSearchInstance.mainIndex.getWidgetUiState({}),
@@ -396,7 +426,9 @@ var index = function index(widgetParams) {
396
426
  var state = helper.state.setQueryParameters(userState);
397
427
  return mainHelper.searchForFacetValues(facetName, facetValue, maxFacetHits, state);
398
428
  };
399
- derivedHelper = mainHelper.derive(function () {
429
+ var isolatedHelper = indexName ? helper : (0, _algoliasearchHelper.default)({}, '__empty_index__', {});
430
+ var derivingHelper = isolated ? isolatedHelper : nearestIsolatedHelper(parent, mainHelper);
431
+ derivedHelper = derivingHelper.derive(function () {
400
432
  return _utils.mergeSearchParameters.apply(void 0, [mainHelper.state].concat(_toConsumableArray((0, _utils.resolveSearchParameters)(_this3))));
401
433
  }, function () {
402
434
  return _this3.getHelper().recommendState;
@@ -538,7 +570,9 @@ var index = function index(widgetParams) {
538
570
 
539
571
  // We only render index widgets if there are no results.
540
572
  // This makes sure `render` is never called with `results` being `null`.
541
- var widgetsToRender = this.getResults() || (_derivedHelper2 = derivedHelper) !== null && _derivedHelper2 !== void 0 && _derivedHelper2.lastRecommendResults ? localWidgets : localWidgets.filter(_utils.isIndexWidget);
573
+ // If it's an isolated index without an index name, we render all widgets,
574
+ // as there are no results to display for the isolated index itself.
575
+ var widgetsToRender = this.getResults() || (_derivedHelper2 = derivedHelper) !== null && _derivedHelper2 !== void 0 && _derivedHelper2.lastRecommendResults || isolated && !indexName ? localWidgets : localWidgets.filter(_utils.isIndexWidget);
542
576
  widgetsToRender = widgetsToRender.filter(function (widget) {
543
577
  if (!widget.shouldRender) {
544
578
  return true;
@@ -572,7 +606,7 @@ var index = function index(widgetParams) {
572
606
  },
573
607
  dispose: function dispose() {
574
608
  var _this5 = this,
575
- _helper2,
609
+ _helper4,
576
610
  _derivedHelper3;
577
611
  localWidgets.forEach(function (widget) {
578
612
  if (widget.dispose && helper) {
@@ -592,13 +626,15 @@ var index = function index(widgetParams) {
592
626
  });
593
627
  localInstantSearchInstance = null;
594
628
  localParent = null;
595
- (_helper2 = helper) === null || _helper2 === void 0 ? void 0 : _helper2.removeAllListeners();
629
+ (_helper4 = helper) === null || _helper4 === void 0 ? void 0 : _helper4.removeAllListeners();
596
630
  helper = null;
597
631
  (_derivedHelper3 = derivedHelper) === null || _derivedHelper3 === void 0 ? void 0 : _derivedHelper3.detach();
598
632
  derivedHelper = null;
599
633
  },
600
634
  getWidgetUiState: function getWidgetUiState(uiState) {
601
- return localWidgets.filter(_utils.isIndexWidget).reduce(function (previousUiState, innerIndex) {
635
+ return localWidgets.filter(_utils.isIndexWidget).filter(function (w) {
636
+ return !w._isolated;
637
+ }).reduce(function (previousUiState, innerIndex) {
602
638
  return innerIndex.getWidgetUiState(previousUiState);
603
639
  }, _objectSpread(_objectSpread({}, uiState), {}, _defineProperty({}, indexId, _objectSpread(_objectSpread({}, uiState[indexId]), localUiState))));
604
640
  },
@@ -634,4 +670,17 @@ function storeRenderState(_ref8) {
634
670
  parent = _ref8.parent;
635
671
  var parentIndexName = parent ? parent.getIndexId() : instantSearchInstance.mainIndex.getIndexId();
636
672
  instantSearchInstance.renderState = _objectSpread(_objectSpread({}, instantSearchInstance.renderState), {}, _defineProperty({}, parentIndexName, _objectSpread(_objectSpread({}, instantSearchInstance.renderState[parentIndexName]), renderState)));
673
+ }
674
+
675
+ /**
676
+ * Walk up the parent chain to find the closest isolated index, or fall back to mainHelper
677
+ */
678
+ function nearestIsolatedHelper(current, mainHelper) {
679
+ while (current) {
680
+ if (current._isolated) {
681
+ return current.getHelper();
682
+ }
683
+ current = current.getParent();
684
+ }
685
+ return mainHelper;
637
686
  }
@@ -4758,8 +4758,8 @@ declare type IndexWidget<TUiState extends UiState = UiState> = Omit<Widget<Index
4758
4758
  getParent: () => IndexWidget | null;
4759
4759
  getWidgets: () => Array<Widget | IndexWidget>;
4760
4760
  createURL: (nextState: SearchParameters | ((state: IndexUiState) => IndexUiState)) => string;
4761
- addWidgets: (widgets: Array<Widget | IndexWidget>) => IndexWidget;
4762
- removeWidgets: (widgets: Array<Widget | IndexWidget>) => IndexWidget;
4761
+ addWidgets: (widgets: Array<Widget | IndexWidget | Widget[]>) => IndexWidget;
4762
+ removeWidgets: (widgets: Array<Widget | IndexWidget | Widget[]>) => IndexWidget;
4763
4763
  init: (options: IndexInitOptions) => void;
4764
4764
  render: (options: IndexRenderOptions) => void;
4765
4765
  dispose: () => void;
@@ -4782,6 +4782,12 @@ declare type IndexWidget<TUiState extends UiState = UiState> = Omit<Widget<Index
4782
4782
  * Can only be called after `init`.
4783
4783
  */
4784
4784
  setIndexUiState: (indexUiState: TUiState[string] | ((previousIndexUiState: TUiState[string]) => TUiState[string])) => void;
4785
+ /**
4786
+ * This index is isolated, meaning it will not be merged with the main
4787
+ * helper's state.
4788
+ * @private
4789
+ */
4790
+ _isolated: boolean;
4785
4791
  };
4786
4792
 
4787
4793
  declare type IndexWidgetDescription = {
@@ -4790,7 +4796,45 @@ declare type IndexWidgetDescription = {
4790
4796
  };
4791
4797
 
4792
4798
  declare type IndexWidgetParams = {
4799
+ /**
4800
+ * The index or composition id to target.
4801
+ */
4793
4802
  indexName: string;
4803
+ /**
4804
+ * Id to use for the index if there are multiple indices with the same name.
4805
+ * This will be used to create the URL and the render state.
4806
+ */
4807
+ indexId?: string;
4808
+ /**
4809
+ * If `true`, the index will not be merged with the main helper's state.
4810
+ * This means that the index will not be part of the main search request.
4811
+ *
4812
+ * @default false
4813
+ */
4814
+ EXPERIMENTAL_isolated?: false;
4815
+ } | {
4816
+ /**
4817
+ * If `true`, the index will not be merged with the main helper's state.
4818
+ * This means that the index will not be part of the main search request.
4819
+ *
4820
+ * This option is EXPERIMENTAL, and implementation details may change in the future.
4821
+ * Things that could change are:
4822
+ * - which widgets get rendered when a change happens
4823
+ * - whether the index searches automatically
4824
+ * - whether the index is included in the URL / UiState
4825
+ * - whether the index is included in server-side rendering
4826
+ *
4827
+ * @default false
4828
+ */
4829
+ EXPERIMENTAL_isolated: true;
4830
+ /**
4831
+ * The index or composition id to target.
4832
+ */
4833
+ indexName?: string;
4834
+ /**
4835
+ * Id to use for the index if there are multiple indices with the same name.
4836
+ * This will be used to create the URL and the render state.
4837
+ */
4794
4838
  indexId?: string;
4795
4839
  };
4796
4840
 
@@ -5125,7 +5169,7 @@ declare class InstantSearch<TUiState extends UiState = UiState, TRouteState = TU
5125
5169
  * Widgets can be added either before or after InstantSearch has started.
5126
5170
  * @param widgets The array of widgets to add to InstantSearch.
5127
5171
  */
5128
- addWidgets(widgets: Array<Widget | IndexWidget>): this;
5172
+ addWidgets(widgets: Array<Widget | IndexWidget | Widget[]>): this;
5129
5173
  /**
5130
5174
  * Removes a widget from the search instance.
5131
5175
  * @deprecated This method will still be supported in 4.x releases, but not further. It is replaced by `removeWidgets([widget])`
@@ -5140,7 +5184,7 @@ declare class InstantSearch<TUiState extends UiState = UiState, TRouteState = TU
5140
5184
  *
5141
5185
  * The widgets must implement a `dispose()` method to clear their states.
5142
5186
  */
5143
- removeWidgets(widgets: Array<Widget | IndexWidget>): this;
5187
+ removeWidgets(widgets: Array<Widget | IndexWidget | Widget[]>): this;
5144
5188
  /**
5145
5189
  * Ends the initialization of InstantSearch.js and triggers the
5146
5190
  * first search.
@@ -1,4 +1,4 @@
1
- /*! InstantSearch.js 4.79.2 | © Algolia, Inc. and contributors; MIT License | https://github.com/algolia/instantsearch */
1
+ /*! InstantSearch.js 4.80.0 | © Algolia, Inc. and contributors; MIT License | https://github.com/algolia/instantsearch */
2
2
  (function (global, factory) {
3
3
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
4
4
  typeof define === 'function' && define.amd ? define(factory) :
@@ -15857,12 +15857,18 @@
15857
15857
  }, []);
15858
15858
  }
15859
15859
  var index = function index(widgetParams) {
15860
- if (widgetParams === undefined || widgetParams.indexName === undefined) {
15860
+ if (widgetParams === undefined || widgetParams.indexName === undefined && !widgetParams.EXPERIMENTAL_isolated) {
15861
15861
  throw new Error(withUsage$u('The `indexName` option is required.'));
15862
15862
  }
15863
- var indexName = widgetParams.indexName,
15863
+
15864
+ // When isolated=true, we use an empty string as the default indexName.
15865
+ // This is intentional: isolated indices do not require a real index name.
15866
+ var _widgetParams$indexNa = widgetParams.indexName,
15867
+ indexName = _widgetParams$indexNa === void 0 ? '' : _widgetParams$indexNa,
15864
15868
  _widgetParams$indexId = widgetParams.indexId,
15865
- indexId = _widgetParams$indexId === void 0 ? indexName : _widgetParams$indexId;
15869
+ indexId = _widgetParams$indexId === void 0 ? indexName : _widgetParams$indexId,
15870
+ _widgetParams$EXPERIM = widgetParams.EXPERIMENTAL_isolated,
15871
+ isolated = _widgetParams$EXPERIM === void 0 ? false : _widgetParams$EXPERIM;
15866
15872
  var localWidgets = [];
15867
15873
  var localUiState = {};
15868
15874
  var localInstantSearchInstance = null;
@@ -15875,6 +15881,7 @@
15875
15881
  return {
15876
15882
  $$type: 'ais.index',
15877
15883
  $$widgetType: 'ais.index',
15884
+ _isolated: isolated,
15878
15885
  getIndexName: function getIndexName() {
15879
15886
  return indexName;
15880
15887
  },
@@ -15926,7 +15933,7 @@
15926
15933
  return resolveScopedResultsFromWidgets(widgetSiblings);
15927
15934
  },
15928
15935
  getParent: function getParent() {
15929
- return localParent;
15936
+ return isolated ? null : localParent;
15930
15937
  },
15931
15938
  createURL: function createURL(nextState) {
15932
15939
  if (typeof nextState === 'function') {
@@ -15945,12 +15952,15 @@
15945
15952
  if (!Array.isArray(widgets)) {
15946
15953
  throw new Error(withUsage$u('The `addWidgets` method expects an array of widgets.'));
15947
15954
  }
15948
- if (widgets.some(function (widget) {
15955
+ var flatWidgets = widgets.reduce(function (acc, w) {
15956
+ return acc.concat(Array.isArray(w) ? w : [w]);
15957
+ }, []);
15958
+ if (flatWidgets.some(function (widget) {
15949
15959
  return typeof widget.init !== 'function' && typeof widget.render !== 'function';
15950
15960
  })) {
15951
15961
  throw new Error(withUsage$u('The widget definition expects a `render` and/or an `init` method.'));
15952
15962
  }
15953
- widgets.forEach(function (widget) {
15963
+ flatWidgets.forEach(function (widget) {
15954
15964
  if (isIndexWidget(widget)) {
15955
15965
  return;
15956
15966
  }
@@ -15965,8 +15975,8 @@
15965
15975
  }
15966
15976
  addWidgetId(widget);
15967
15977
  });
15968
- localWidgets = localWidgets.concat(widgets);
15969
- if (localInstantSearchInstance && Boolean(widgets.length)) {
15978
+ localWidgets = localWidgets.concat(flatWidgets);
15979
+ if (localInstantSearchInstance && Boolean(flatWidgets.length)) {
15970
15980
  privateHelperSetState(helper, {
15971
15981
  state: getLocalWidgetsSearchParameters(localWidgets, {
15972
15982
  uiState: localUiState,
@@ -15982,7 +15992,7 @@
15982
15992
  // We compute the render state before calling `init` in a separate loop
15983
15993
  // to construct the whole render state object that is then passed to
15984
15994
  // `init`.
15985
- widgets.forEach(function (widget) {
15995
+ flatWidgets.forEach(function (widget) {
15986
15996
  if (widget.getRenderState) {
15987
15997
  var renderState = widget.getRenderState(localInstantSearchInstance.renderState[_this.getIndexId()] || {}, createInitArgs(localInstantSearchInstance, _this, localInstantSearchInstance._initialUiState));
15988
15998
  storeRenderState({
@@ -15992,12 +16002,17 @@
15992
16002
  });
15993
16003
  }
15994
16004
  });
15995
- widgets.forEach(function (widget) {
16005
+ flatWidgets.forEach(function (widget) {
15996
16006
  if (widget.init) {
15997
16007
  widget.init(createInitArgs(localInstantSearchInstance, _this, localInstantSearchInstance._initialUiState));
15998
16008
  }
15999
16009
  });
16000
- localInstantSearchInstance.scheduleSearch();
16010
+ if (isolated) {
16011
+ var _helper2;
16012
+ (_helper2 = helper) === null || _helper2 === void 0 ? void 0 : _helper2.search();
16013
+ } else {
16014
+ localInstantSearchInstance.scheduleSearch();
16015
+ }
16001
16016
  }
16002
16017
  return this;
16003
16018
  },
@@ -16006,13 +16021,16 @@
16006
16021
  if (!Array.isArray(widgets)) {
16007
16022
  throw new Error(withUsage$u('The `removeWidgets` method expects an array of widgets.'));
16008
16023
  }
16009
- if (widgets.some(function (widget) {
16024
+ var flatWidgets = widgets.reduce(function (acc, w) {
16025
+ return acc.concat(Array.isArray(w) ? w : [w]);
16026
+ }, []);
16027
+ if (flatWidgets.some(function (widget) {
16010
16028
  return typeof widget.dispose !== 'function';
16011
16029
  })) {
16012
16030
  throw new Error(withUsage$u('The widget definition expects a `dispose` method.'));
16013
16031
  }
16014
16032
  localWidgets = localWidgets.filter(function (widget) {
16015
- return widgets.indexOf(widget) === -1;
16033
+ return flatWidgets.indexOf(widget) === -1;
16016
16034
  });
16017
16035
  localWidgets.forEach(function (widget) {
16018
16036
  if (isIndexWidget(widget)) {
@@ -16028,8 +16046,8 @@
16028
16046
  hasSearchWidget = true;
16029
16047
  }
16030
16048
  });
16031
- if (localInstantSearchInstance && Boolean(widgets.length)) {
16032
- var _widgets$reduce = widgets.reduce(function (states, widget) {
16049
+ if (localInstantSearchInstance && Boolean(flatWidgets.length)) {
16050
+ var _flatWidgets$reduce = flatWidgets.reduce(function (states, widget) {
16033
16051
  // the `dispose` method exists at this point we already assert it
16034
16052
  var next = widget.dispose({
16035
16053
  helper: helper,
@@ -16047,8 +16065,8 @@
16047
16065
  cleanedSearchState: helper.state,
16048
16066
  cleanedRecommendState: helper.recommendState
16049
16067
  }),
16050
- cleanedSearchState = _widgets$reduce.cleanedSearchState,
16051
- cleanedRecommendState = _widgets$reduce.cleanedRecommendState;
16068
+ cleanedSearchState = _flatWidgets$reduce.cleanedSearchState,
16069
+ cleanedRecommendState = _flatWidgets$reduce.cleanedRecommendState;
16052
16070
  var newState = localInstantSearchInstance.future.preserveSharedStateOnUnmount ? getLocalWidgetsSearchParameters(localWidgets, {
16053
16071
  uiState: localUiState,
16054
16072
  initialSearchParameters: new algoliasearchHelper_1.SearchParameters({
@@ -16068,7 +16086,12 @@
16068
16086
  helper.setState(newState);
16069
16087
  helper.recommendState = cleanedRecommendState;
16070
16088
  if (localWidgets.length) {
16071
- localInstantSearchInstance.scheduleSearch();
16089
+ if (isolated) {
16090
+ var _helper3;
16091
+ (_helper3 = helper) === null || _helper3 === void 0 ? void 0 : _helper3.search();
16092
+ } else {
16093
+ localInstantSearchInstance.scheduleSearch();
16094
+ }
16072
16095
  }
16073
16096
  }
16074
16097
  return this;
@@ -16106,13 +16129,20 @@
16106
16129
  // This Helper is only used for state management we do not care about the
16107
16130
  // `searchClient`. Only the "main" Helper created at the `InstantSearch`
16108
16131
  // level is aware of the client.
16109
- helper = algoliasearchHelper_1({}, parameters.index, parameters);
16132
+ helper = algoliasearchHelper_1(mainHelper.getClient(), parameters.index, parameters);
16110
16133
  helper.recommendState = recommendParameters;
16111
16134
 
16112
16135
  // We forward the call to `search` to the "main" instance of the Helper
16113
16136
  // which is responsible for managing the queries (it's the only one that is
16114
16137
  // aware of the `searchClient`).
16115
16138
  helper.search = function () {
16139
+ if (isolated) {
16140
+ instantSearchInstance.status = 'loading';
16141
+ _this3.render({
16142
+ instantSearchInstance: instantSearchInstance
16143
+ });
16144
+ return instantSearchInstance.compositionID ? helper.searchWithComposition() : helper.searchOnlyWithDerivedHelpers();
16145
+ }
16116
16146
  if (instantSearchInstance.onStateChange) {
16117
16147
  instantSearchInstance.onStateChange({
16118
16148
  uiState: instantSearchInstance.mainIndex.getWidgetUiState({}),
@@ -16136,7 +16166,9 @@
16136
16166
  var state = helper.state.setQueryParameters(userState);
16137
16167
  return mainHelper.searchForFacetValues(facetName, facetValue, maxFacetHits, state);
16138
16168
  };
16139
- derivedHelper = mainHelper.derive(function () {
16169
+ var isolatedHelper = indexName ? helper : algoliasearchHelper_1({}, '__empty_index__', {});
16170
+ var derivingHelper = isolated ? isolatedHelper : nearestIsolatedHelper(parent, mainHelper);
16171
+ derivedHelper = derivingHelper.derive(function () {
16140
16172
  return mergeSearchParameters.apply(void 0, [mainHelper.state].concat(_toConsumableArray(resolveSearchParameters(_this3))));
16141
16173
  }, function () {
16142
16174
  return _this3.getHelper().recommendState;
@@ -16278,7 +16310,9 @@
16278
16310
 
16279
16311
  // We only render index widgets if there are no results.
16280
16312
  // This makes sure `render` is never called with `results` being `null`.
16281
- var widgetsToRender = this.getResults() || (_derivedHelper2 = derivedHelper) !== null && _derivedHelper2 !== void 0 && _derivedHelper2.lastRecommendResults ? localWidgets : localWidgets.filter(isIndexWidget);
16313
+ // If it's an isolated index without an index name, we render all widgets,
16314
+ // as there are no results to display for the isolated index itself.
16315
+ var widgetsToRender = this.getResults() || (_derivedHelper2 = derivedHelper) !== null && _derivedHelper2 !== void 0 && _derivedHelper2.lastRecommendResults || isolated && !indexName ? localWidgets : localWidgets.filter(isIndexWidget);
16282
16316
  widgetsToRender = widgetsToRender.filter(function (widget) {
16283
16317
  if (!widget.shouldRender) {
16284
16318
  return true;
@@ -16312,7 +16346,7 @@
16312
16346
  },
16313
16347
  dispose: function dispose() {
16314
16348
  var _this5 = this,
16315
- _helper2,
16349
+ _helper4,
16316
16350
  _derivedHelper3;
16317
16351
  localWidgets.forEach(function (widget) {
16318
16352
  if (widget.dispose && helper) {
@@ -16332,13 +16366,15 @@
16332
16366
  });
16333
16367
  localInstantSearchInstance = null;
16334
16368
  localParent = null;
16335
- (_helper2 = helper) === null || _helper2 === void 0 ? void 0 : _helper2.removeAllListeners();
16369
+ (_helper4 = helper) === null || _helper4 === void 0 ? void 0 : _helper4.removeAllListeners();
16336
16370
  helper = null;
16337
16371
  (_derivedHelper3 = derivedHelper) === null || _derivedHelper3 === void 0 ? void 0 : _derivedHelper3.detach();
16338
16372
  derivedHelper = null;
16339
16373
  },
16340
16374
  getWidgetUiState: function getWidgetUiState(uiState) {
16341
- return localWidgets.filter(isIndexWidget).reduce(function (previousUiState, innerIndex) {
16375
+ return localWidgets.filter(isIndexWidget).filter(function (w) {
16376
+ return !w._isolated;
16377
+ }).reduce(function (previousUiState, innerIndex) {
16342
16378
  return innerIndex.getWidgetUiState(previousUiState);
16343
16379
  }, _objectSpread2(_objectSpread2({}, uiState), {}, _defineProperty({}, indexId, _objectSpread2(_objectSpread2({}, uiState[indexId]), localUiState))));
16344
16380
  },
@@ -16375,6 +16411,19 @@
16375
16411
  instantSearchInstance.renderState = _objectSpread2(_objectSpread2({}, instantSearchInstance.renderState), {}, _defineProperty({}, parentIndexName, _objectSpread2(_objectSpread2({}, instantSearchInstance.renderState[parentIndexName]), renderState)));
16376
16412
  }
16377
16413
 
16414
+ /**
16415
+ * Walk up the parent chain to find the closest isolated index, or fall back to mainHelper
16416
+ */
16417
+ function nearestIsolatedHelper(current, mainHelper) {
16418
+ while (current) {
16419
+ if (current._isolated) {
16420
+ return current.getHelper();
16421
+ }
16422
+ current = current.getParent();
16423
+ }
16424
+ return mainHelper;
16425
+ }
16426
+
16378
16427
  function formatNumber(value, numberLocale) {
16379
16428
  return value.toLocaleString(numberLocale);
16380
16429
  }
@@ -16440,7 +16489,7 @@
16440
16489
  };
16441
16490
  }
16442
16491
 
16443
- var version$1 = '4.79.2';
16492
+ var version$1 = '4.80.0';
16444
16493
 
16445
16494
  var withUsage$v = createDocumentationMessageGenerator({
16446
16495
  name: 'instantsearch'
@@ -16741,12 +16790,9 @@
16741
16790
  if (!Array.isArray(widgets)) {
16742
16791
  throw new Error(withUsage$v('The `addWidgets` method expects an array of widgets. Please use `addWidget`.'));
16743
16792
  }
16744
- if (widgets.some(function (widget) {
16745
- return typeof widget.init !== 'function' && typeof widget.render !== 'function';
16793
+ if (this.compositionID && widgets.some(function (w) {
16794
+ return !Array.isArray(w) && isIndexWidget(w) && !w._isolated;
16746
16795
  })) {
16747
- throw new Error(withUsage$v('The widget definition expects a `render` and/or an `init` method.'));
16748
- }
16749
- if (this.compositionID && widgets.some(isIndexWidget)) {
16750
16796
  throw new Error(withUsage$v('The `index` widget cannot be used with a composition-based InstantSearch implementation.'));
16751
16797
  }
16752
16798
  this.mainIndex.addWidgets(widgets);
@@ -16779,11 +16825,6 @@
16779
16825
  if (!Array.isArray(widgets)) {
16780
16826
  throw new Error(withUsage$v('The `removeWidgets` method expects an array of widgets. Please use `removeWidget`.'));
16781
16827
  }
16782
- if (widgets.some(function (widget) {
16783
- return typeof widget.dispose !== 'function';
16784
- })) {
16785
- throw new Error(withUsage$v('The widget definition expects a `dispose` method.'));
16786
- }
16787
16828
  this.mainIndex.removeWidgets(widgets);
16788
16829
  return this;
16789
16830
  }
@@ -19068,7 +19109,7 @@
19068
19109
  });
19069
19110
  // if there is one TextNode first and one TextNode last, the
19070
19111
  // last one's nodeValue will be assigned to the first.
19071
- if (this.nodes[0].nodeValue) {
19112
+ if (this.nodes[0] && this.nodes[0].nodeValue) {
19072
19113
  this.nodes[0].nodeValue = '';
19073
19114
  }
19074
19115
  }