react-instantsearch-core 7.31.0 → 7.32.1

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.
@@ -1,4 +1,4 @@
1
- /*! React InstantSearch Core 7.31.0 | © Algolia, Inc. and contributors; MIT License | https://github.com/algolia/instantsearch */
1
+ /*! React InstantSearch Core 7.32.1 | © Algolia, Inc. and contributors; MIT License | https://github.com/algolia/instantsearch */
2
2
  (function (global, factory) {
3
3
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) :
4
4
  typeof define === 'function' && define.amd ? define(['exports', 'react'], factory) :
@@ -24,7 +24,7 @@
24
24
 
25
25
  var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
26
26
 
27
- var version$2 = '7.31.0';
27
+ var version$2 = '7.32.1';
28
28
 
29
29
  function _define_property(obj, key, value) {
30
30
  if (key in obj) {
@@ -3919,7 +3919,7 @@
3919
3919
  function requireVersion() {
3920
3920
  if (hasRequiredVersion) return version$1;
3921
3921
  hasRequiredVersion = 1;
3922
- version$1 = '3.28.2';
3922
+ version$1 = '3.29.0';
3923
3923
  return version$1;
3924
3924
  }
3925
3925
 
@@ -5293,7 +5293,6 @@
5293
5293
  var derivedStateQueries = requestBuilder._getCompositionQueries(derivedState);
5294
5294
  states.push({
5295
5295
  state: derivedState,
5296
- queriesCount: derivedStateQueries.length,
5297
5296
  helper: derivedHelper
5298
5297
  });
5299
5298
  derivedHelper.emit('search', {
@@ -5423,7 +5422,7 @@
5423
5422
  var state = s.state;
5424
5423
  var queriesCount = s.queriesCount;
5425
5424
  var helper = s.helper;
5426
- var specificResults = results.splice(0, queriesCount);
5425
+ var specificResults = queriesCount !== undefined ? results.splice(0, queriesCount) : results;
5427
5426
  if (!state.index) {
5428
5427
  helper.emit('result', {
5429
5428
  results: null,
@@ -5431,8 +5430,24 @@
5431
5430
  });
5432
5431
  return;
5433
5432
  }
5434
- helper.lastResults = new SearchResults(state, specificResults, self._searchResultsOptions);
5435
- if (rawContent !== undefined) helper.lastResults._rawContent = rawContent;
5433
+ // Multifeed composition: build ordered SearchResults array on lastResults
5434
+ if (specificResults.length > 0 && specificResults[0].feedID) {
5435
+ var feeds = specificResults.map(function(r) {
5436
+ var sr = new SearchResults(state, [
5437
+ r
5438
+ ], self._searchResultsOptions);
5439
+ if (rawContent !== undefined) sr._rawContent = rawContent;
5440
+ return sr;
5441
+ });
5442
+ helper.lastResults = new SearchResults(state, [
5443
+ specificResults[0]
5444
+ ], self._searchResultsOptions);
5445
+ helper.lastResults.feeds = feeds;
5446
+ if (rawContent !== undefined) helper.lastResults._rawContent = rawContent;
5447
+ } else {
5448
+ helper.lastResults = new SearchResults(state, specificResults, self._searchResultsOptions);
5449
+ if (rawContent !== undefined) helper.lastResults._rawContent = rawContent;
5450
+ }
5436
5451
  helper.emit('result', {
5437
5452
  results: helper.lastResults,
5438
5453
  state: state
@@ -5965,7 +5980,7 @@
5965
5980
  }
5966
5981
  }
5967
5982
 
5968
- var withUsage$t = createDocumentationMessageGenerator({
5983
+ var withUsage$u = createDocumentationMessageGenerator({
5969
5984
  name: 'configure',
5970
5985
  connector: true
5971
5986
  });
@@ -5981,7 +5996,7 @@
5981
5996
  var renderFn = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : noop, unmountFn = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : noop;
5982
5997
  return function(widgetParams) {
5983
5998
  if (!widgetParams || !isPlainObject(widgetParams.searchParameters)) {
5984
- throw new Error(withUsage$t('The `searchParameters` option expects an object.'));
5999
+ throw new Error(withUsage$u('The `searchParameters` option expects an object.'));
5985
6000
  }
5986
6001
  var connectorState = {};
5987
6002
  function refine(helper) {
@@ -6265,224 +6280,1327 @@
6265
6280
  return stableValue;
6266
6281
  }
6267
6282
 
6268
- var useKey = 'use';
6269
- // @TODO: Remove this file and import directly from React when available.
6270
- var use = React__namespace[useKey];
6283
+ var id = 0;
6284
+ function addWidgetId(widget) {
6285
+ if (widget.dependsOn !== 'recommend') {
6286
+ return;
6287
+ }
6288
+ widget.$$id = id++;
6289
+ }
6290
+ function resetWidgetId() {
6291
+ id = 0;
6292
+ }
6271
6293
 
6272
- /**
6273
- * `useLayoutEffect` that doesn't show a warning when server-side rendering.
6274
- *
6275
- * It uses `useEffect` on the server (no-op), and `useLayoutEffect` on the browser.
6276
- */ var useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;
6294
+ function _array_without_holes(arr) {
6295
+ if (Array.isArray(arr)) return _array_like_to_array(arr);
6296
+ }
6277
6297
 
6278
- var InstantSearchRSCContext = React.createContext({
6279
- countRef: {
6280
- current: 0
6281
- },
6282
- waitForResultsRef: null,
6283
- ignoreMultipleHooksWarning: false
6284
- });
6298
+ function _non_iterable_spread() {
6299
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
6300
+ }
6285
6301
 
6286
- function useRSCContext() {
6287
- return React.useContext(InstantSearchRSCContext);
6302
+ function _to_consumable_array(arr) {
6303
+ return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
6288
6304
  }
6289
6305
 
6290
- /* eslint-disable no-console, no-empty */ var warnCache = {
6291
- current: {}
6292
- };
6293
- /**
6294
- * Logs a warning if the condition is not met.
6295
- * This is used to log issues in development environment only.
6296
- */ function warn(condition, message) {
6297
- if (condition) {
6298
- return;
6299
- }
6300
- var sanitizedMessage = message.trim();
6301
- var hasAlreadyPrinted = warnCache.current[sanitizedMessage];
6302
- if (!hasAlreadyPrinted) {
6303
- warnCache.current[sanitizedMessage] = true;
6304
- var warning = "[InstantSearch] ".concat(sanitizedMessage);
6305
- console.warn(warning);
6306
- try {
6307
- // Welcome to debugging InstantSearch.
6308
- //
6309
- // This error was thrown as a convenience so that you can find the source
6310
- // of the warning that appears in the console by enabling "Pause on exceptions"
6311
- // in your debugger.
6312
- throw new Error(warning);
6313
- } catch (error) {}
6306
+ function getObjectType(object) {
6307
+ return Object.prototype.toString.call(object).slice(8, -1);
6308
+ }
6309
+
6310
+ function checkRendering(rendering, usage) {
6311
+ if (rendering === undefined || typeof rendering !== 'function') {
6312
+ throw new Error("The render function is not valid (received type ".concat(getObjectType(rendering), ").\n\n").concat(usage));
6314
6313
  }
6315
6314
  }
6316
6315
 
6317
- function useWidget(param) {
6318
- var widget = param.widget, parentIndex = param.parentIndex, props = param.props, shouldSsr = param.shouldSsr, skipSuspense = param.skipSuspense;
6319
- var _waitForResultsRef_current, _waitForResultsRef_current1;
6320
- var _useRSCContext = useRSCContext(), waitForResultsRef = _useRSCContext.waitForResultsRef, countRef = _useRSCContext.countRef, ignoreMultipleHooksWarning = _useRSCContext.ignoreMultipleHooksWarning;
6321
- var prevPropsRef = React.useRef(props);
6322
- React.useEffect(function() {
6323
- prevPropsRef.current = props;
6324
- }, [
6325
- props
6326
- ]);
6327
- var prevWidgetRef = React.useRef(widget);
6328
- React.useEffect(function() {
6329
- prevWidgetRef.current = widget;
6330
- }, [
6331
- widget
6332
- ]);
6333
- var cleanupTimerRef = React.useRef(null);
6334
- var shouldAddWidgetEarly = shouldSsr && !parentIndex.getWidgets().includes(widget);
6335
- var search = useInstantSearchContext();
6336
- // This effect is responsible for adding, removing, and updating the widget.
6337
- // We need to support scenarios where the widget is remounted quickly, like in
6338
- // Strict Mode, so that we don't lose its state, and therefore that we don't
6339
- // break routing.
6340
- useIsomorphicLayoutEffect(function() {
6341
- var previousWidget = prevWidgetRef.current;
6342
- // Scenario 1: the widget is added for the first time.
6343
- if (!cleanupTimerRef.current) {
6344
- if (!shouldSsr) {
6345
- parentIndex.addWidgets([
6346
- widget
6347
- ]);
6348
- }
6349
- } else {
6350
- // We cancel the original effect cleanup because it may not be necessary if
6351
- // props haven't changed. (We manually call it if it is below.)
6352
- clearTimeout(cleanupTimerRef.current);
6353
- // Warning: if an unstable function prop is provided, `dequal` is not able
6354
- // to keep its reference and therefore will consider that props did change.
6355
- // This could unsollicitely remove/add the widget, therefore forget its state,
6356
- // and could be a source of confusion.
6357
- // If users face this issue, we should advise them to provide stable function
6358
- // references.
6359
- var arePropsEqual = dequal(props, prevPropsRef.current);
6360
- // If props did change, then we execute the cleanup function instantly
6361
- // and then add the widget back. This lets us add the widget without
6362
- // waiting for the scheduled cleanup function to finish (that we canceled
6363
- // above).
6364
- if (!arePropsEqual) {
6365
- parentIndex.removeWidgets([
6366
- previousWidget
6367
- ]);
6368
- parentIndex.addWidgets([
6369
- widget
6370
- ]);
6371
- }
6316
+ /**
6317
+ * Clears the refinements of a SearchParameters object based on rules provided.
6318
+ * The included attributes list is applied before the excluded attributes list. If the list
6319
+ * is not provided, this list of all the currently refined attributes is used as included attributes.
6320
+ * @returns search parameters with refinements cleared
6321
+ */ function clearRefinements(param) {
6322
+ var helper = param.helper, _param_attributesToClear = param.attributesToClear, attributesToClear = _param_attributesToClear === void 0 ? [] : _param_attributesToClear;
6323
+ var finalState = helper.state.setPage(0);
6324
+ finalState = attributesToClear.reduce(function(state, attribute) {
6325
+ if (finalState.isNumericRefined(attribute)) {
6326
+ return state.removeNumericRefinement(attribute);
6372
6327
  }
6373
- return function() {
6374
- // We don't remove the widget right away, but rather schedule it so that
6375
- // we're able to cancel it in the next effect.
6376
- cleanupTimerRef.current = setTimeout(function() {
6377
- search._schedule(function() {
6378
- if (search._preventWidgetCleanup) return;
6379
- parentIndex.removeWidgets([
6380
- previousWidget
6381
- ]);
6382
- });
6383
- });
6384
- };
6385
- }, [
6386
- parentIndex,
6387
- widget,
6388
- shouldSsr,
6389
- search,
6390
- props
6391
- ]);
6392
- if (shouldAddWidgetEarly || (waitForResultsRef === null || waitForResultsRef === void 0 ? void 0 : (_waitForResultsRef_current = waitForResultsRef.current) === null || _waitForResultsRef_current === void 0 ? void 0 : _waitForResultsRef_current.status) === 'pending') {
6393
- parentIndex.addWidgets([
6394
- widget
6395
- ]);
6396
- }
6397
- if ((waitForResultsRef === null || waitForResultsRef === void 0 ? void 0 : waitForResultsRef.current) && !skipSuspense) {
6398
- var _search_helper;
6399
- use(waitForResultsRef.current);
6400
- // If we made a second request because of DynamicWidgets, we need to wait for the second result,
6401
- // except for DynamicWidgets itself which needs to render its children after the first result.
6402
- if (widget.$$type !== 'ais.dynamicWidgets' && ((_search_helper = search.helper) === null || _search_helper === void 0 ? void 0 : _search_helper.lastResults)) {
6403
- use(waitForResultsRef.current);
6328
+ if (finalState.isHierarchicalFacet(attribute)) {
6329
+ return state.removeHierarchicalFacetRefinement(attribute);
6404
6330
  }
6331
+ if (finalState.isDisjunctiveFacet(attribute)) {
6332
+ return state.removeDisjunctiveFacetRefinement(attribute);
6333
+ }
6334
+ if (finalState.isConjunctiveFacet(attribute)) {
6335
+ return state.removeFacetRefinement(attribute);
6336
+ }
6337
+ return state;
6338
+ }, finalState);
6339
+ if (attributesToClear.indexOf('query') !== -1) {
6340
+ finalState = finalState.setQuery('');
6405
6341
  }
6406
- if ((waitForResultsRef === null || waitForResultsRef === void 0 ? void 0 : (_waitForResultsRef_current1 = waitForResultsRef.current) === null || _waitForResultsRef_current1 === void 0 ? void 0 : _waitForResultsRef_current1.status) === 'fulfilled') {
6407
- countRef.current += 1;
6408
- { warn(ignoreMultipleHooksWarning || countRef.current <= parentIndex.getWidgets().length, "We detected you may have a component with multiple InstantSearch hooks.\n\nWith Next.js, you need to set `skipSuspense` to `true` for all but the last hook in the component, otherwise, only the first hook will be rendered on the server.\n\nThis warning can be a false positive if you are using dynamic widgets or multi-index, in which case you can ignore it by setting `ignoreMultipleHooksWarning` to `true` in `<InstantSearchNext`.\n\nFor more information, see https://www.algolia.com/doc/guides/building-search-ui/going-further/server-side-rendering/react/#composing-hooks"); }
6409
- }
6342
+ return finalState;
6410
6343
  }
6411
6344
 
6412
- function useConnector(connector) {
6413
- var _1 = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : void 0, _2 = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : void 0;
6414
- var _ref = [
6415
- _1,
6416
- _2
6417
- ], _ref1 = _to_array(_ref), tmp = _ref1[0], props = tmp === void 0 ? {} : tmp, _rest = _ref1.slice(1), _rest1 = _sliced_to_array(_rest, 1), tmp1 = _rest1[0], _ref2 = tmp1 === void 0 ? {} : tmp1, _ref_skipSuspense = _ref2.skipSuspense, skipSuspense = _ref_skipSuspense === void 0 ? false : _ref_skipSuspense, additionalWidgetProperties = _object_without_properties(_ref2, [
6418
- "skipSuspense"
6419
- ]);
6420
- var serverContext = useInstantSearchServerContext();
6421
- var ssrContext = useInstantSearchSSRContext();
6422
- var search = useInstantSearchContext();
6423
- var parentIndex = useIndexContext();
6424
- var stableProps = useStableValue(props);
6425
- var stableAdditionalWidgetProperties = useStableValue(additionalWidgetProperties);
6426
- var shouldSetStateRef = React.useRef(true);
6427
- var previousRenderStateRef = React.useRef(null);
6428
- var previousStatusRef = React.useRef(search.status);
6429
- var widget = React.useMemo(function() {
6430
- var createWidget = connector(function(connectorState, isFirstRender) {
6431
- // We skip the `init` widget render because:
6432
- // - We rely on `getWidgetRenderState` to compute the initial state before
6433
- // the InstantSearch.js lifecycle starts.
6434
- // - It prevents UI flashes when updating the widget props.
6435
- if (isFirstRender) {
6436
- shouldSetStateRef.current = true;
6437
- return;
6438
- }
6439
- // There are situations where InstantSearch.js may render widgets slightly
6440
- // after they're removed by React, and thus try to update the React state
6441
- // on unmounted components. React 16 and 17 consider them as memory leaks
6442
- // and display a warning.
6443
- // This happens in <DynamicWidgets> when `attributesToRender` contains a
6444
- // value without an attribute previously mounted. React will unmount the
6445
- // component controlled by that attribute, but InstantSearch.js will stay
6446
- // unaware of this change until the render pass finishes, and therefore
6447
- // notifies of a state change.
6448
- // This ref lets us track this situation and ignore these state updates.
6449
- if (shouldSetStateRef.current) {
6450
- var instantSearchInstance = connectorState.instantSearchInstance; connectorState.widgetParams; var renderState = _object_without_properties(connectorState, [
6451
- "instantSearchInstance",
6452
- "widgetParams"
6453
- ]);
6454
- // We only update the state when a widget render state param changes,
6455
- // except for functions. We ignore function reference changes to avoid
6456
- // infinite loops. It's safe to omit them because they get updated
6457
- // every time another render param changes.
6458
- if (!dequal(renderState, previousRenderStateRef.current, function(a, b) {
6459
- return (a === null || a === void 0 ? void 0 : a.constructor) === Function && (b === null || b === void 0 ? void 0 : b.constructor) === Function;
6460
- }) || instantSearchInstance.status !== previousStatusRef.current) {
6461
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
6462
- setState(renderState);
6463
- previousRenderStateRef.current = renderState;
6464
- previousStatusRef.current = instantSearchInstance.status;
6465
- }
6466
- }
6467
- }, function() {
6468
- // We'll ignore the next state update until we know for sure that
6469
- // InstantSearch.js re-inits the component.
6470
- shouldSetStateRef.current = false;
6471
- });
6472
- return _object_spread({}, createWidget(stableProps), stableAdditionalWidgetProperties);
6473
- }, [
6474
- connector,
6475
- stableProps,
6476
- stableAdditionalWidgetProperties
6477
- ]);
6478
- var _useState = _sliced_to_array(React.useState(function() {
6479
- if (widget.getWidgetRenderState) {
6480
- var _widget_getWidgetSearchParameters;
6481
- // The helper exists because we've started InstantSearch.
6482
- var helper = parentIndex.getHelper();
6483
- var uiState = parentIndex.getWidgetUiState({})[parentIndex.getIndexId()];
6484
- helper.state = ((_widget_getWidgetSearchParameters = widget.getWidgetSearchParameters) === null || _widget_getWidgetSearchParameters === void 0 ? void 0 : _widget_getWidgetSearchParameters.call(widget, helper.state, {
6485
- uiState: uiState
6345
+ function _extends() {
6346
+ _extends = Object.assign || function assign(target) {
6347
+ for (var i = 1; i < arguments.length; i++) {
6348
+ var source = arguments[i];
6349
+ for (var key in source) if (Object.prototype.hasOwnProperty.call(source, key)) target[key] = source[key];
6350
+ }
6351
+
6352
+ return target;
6353
+ };
6354
+
6355
+ return _extends.apply(this, arguments);
6356
+ }
6357
+
6358
+ function _object_destructuring_empty(o) {
6359
+ if (o === null || o === void 0) throw new TypeError("Cannot destructure " + o);
6360
+
6361
+ return o;
6362
+ }
6363
+
6364
+ /**
6365
+ * This implementation is taken from Lodash implementation.
6366
+ * See: https://github.com/lodash/lodash/blob/4.17.11-npm/escape.js
6367
+ */ // Used to map characters to HTML entities.
6368
+ var htmlEntities = {
6369
+ '&': '&amp;',
6370
+ '<': '&lt;',
6371
+ '>': '&gt;',
6372
+ '"': '&quot;',
6373
+ "'": '&#39;'
6374
+ };
6375
+ // Used to match HTML entities and HTML characters.
6376
+ var regexUnescapedHtml = /[&<>"']/g;
6377
+ var regexHasUnescapedHtml = RegExp(regexUnescapedHtml.source);
6378
+ /**
6379
+ * Converts the characters "&", "<", ">", '"', and "'" in `string` to their
6380
+ * corresponding HTML entities.
6381
+ */ function escape$1(value) {
6382
+ return value && regexHasUnescapedHtml.test(value) ? value.replace(regexUnescapedHtml, function(character) {
6383
+ return htmlEntities[character];
6384
+ }) : value;
6385
+ }
6386
+ /**
6387
+ * This implementation is taken from Lodash implementation.
6388
+ * See: https://github.com/lodash/lodash/blob/4.17.11-npm/unescape.js
6389
+ */ // Used to map HTML entities to characters.
6390
+ var htmlCharacters = {
6391
+ '&amp;': '&',
6392
+ '&lt;': '<',
6393
+ '&gt;': '>',
6394
+ '&quot;': '"',
6395
+ '&#39;': "'"
6396
+ };
6397
+ // Used to match HTML entities and HTML characters.
6398
+ var regexEscapedHtml = /&(amp|quot|lt|gt|#39);/g;
6399
+ var regexHasEscapedHtml = RegExp(regexEscapedHtml.source);
6400
+ /**
6401
+ * Converts the HTML entities "&", "<", ">", '"', and "'" in `string` to their
6402
+ * characters.
6403
+ */ function unescape$1(value) {
6404
+ return value && regexHasEscapedHtml.test(value) ? value.replace(regexEscapedHtml, function(character) {
6405
+ return htmlCharacters[character];
6406
+ }) : value;
6407
+ }
6408
+
6409
+ var TAG_PLACEHOLDER = {
6410
+ highlightPreTag: '__ais-highlight__',
6411
+ highlightPostTag: '__/ais-highlight__'
6412
+ };
6413
+ var TAG_REPLACEMENT = {
6414
+ highlightPreTag: '<mark>',
6415
+ highlightPostTag: '</mark>'
6416
+ };
6417
+ // @MAJOR: in the future, this should only escape, not replace
6418
+ function replaceTagsAndEscape(value) {
6419
+ return escape$1(value).replace(new RegExp(TAG_PLACEHOLDER.highlightPreTag, 'g'), TAG_REPLACEMENT.highlightPreTag).replace(new RegExp(TAG_PLACEHOLDER.highlightPostTag, 'g'), TAG_REPLACEMENT.highlightPostTag);
6420
+ }
6421
+ function recursiveEscape(input) {
6422
+ if (isPlainObject(input) && typeof input.value !== 'string') {
6423
+ return Object.keys(input).reduce(function(acc, key) {
6424
+ return _object_spread_props(_object_spread({}, acc), _define_property({}, key, recursiveEscape(input[key])));
6425
+ }, {});
6426
+ }
6427
+ if (Array.isArray(input)) {
6428
+ return input.map(recursiveEscape);
6429
+ }
6430
+ return _object_spread_props(_object_spread({}, input), {
6431
+ value: replaceTagsAndEscape(input.value)
6432
+ });
6433
+ }
6434
+ function escapeHits(hits) {
6435
+ if (hits.__escaped === undefined) {
6436
+ // We don't override the value on hit because it will mutate the raw results
6437
+ // instead we make a shallow copy and we assign the escaped values on it.
6438
+ hits = hits.map(function(_0) {
6439
+ _object_destructuring_empty(_0);
6440
+ var hit = _extends({}, _0);
6441
+ if (hit._highlightResult) {
6442
+ hit._highlightResult = recursiveEscape(hit._highlightResult);
6443
+ }
6444
+ if (hit._snippetResult) {
6445
+ hit._snippetResult = recursiveEscape(hit._snippetResult);
6446
+ }
6447
+ return hit;
6448
+ });
6449
+ hits.__escaped = true;
6450
+ }
6451
+ return hits;
6452
+ }
6453
+ function escapeFacets(facetHits) {
6454
+ return facetHits.map(function(h) {
6455
+ return _object_spread_props(_object_spread({}, h), {
6456
+ highlighted: replaceTagsAndEscape(h.highlighted)
6457
+ });
6458
+ });
6459
+ }
6460
+
6461
+ function concatHighlightedParts(parts) {
6462
+ var highlightPreTag = TAG_REPLACEMENT.highlightPreTag, highlightPostTag = TAG_REPLACEMENT.highlightPostTag;
6463
+ return parts.map(function(part) {
6464
+ return part.isHighlighted ? highlightPreTag + part.value + highlightPostTag : part.value;
6465
+ }).join('');
6466
+ }
6467
+
6468
+ function isFacetRefined(helper, facet, value) {
6469
+ if (helper.state.isHierarchicalFacet(facet)) {
6470
+ return helper.state.isHierarchicalFacetRefined(facet, value);
6471
+ } else if (helper.state.isConjunctiveFacet(facet)) {
6472
+ return helper.state.isFacetRefined(facet, value);
6473
+ } else {
6474
+ return helper.state.isDisjunctiveFacetRefined(facet, value);
6475
+ }
6476
+ }
6477
+
6478
+ function createSendEventForFacet(param) {
6479
+ var instantSearchInstance = param.instantSearchInstance, helper = param.helper, attr = param.attribute, widgetType = param.widgetType;
6480
+ var sendEventForFacet = function sendEventForFacet() {
6481
+ for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
6482
+ args[_key] = arguments[_key];
6483
+ }
6484
+ var _args = _sliced_to_array(args, 4), facetValue = _args[1], tmp = _args[2], eventName = tmp === void 0 ? 'Filter Applied' : tmp, tmp1 = _args[3], additionalData = tmp1 === void 0 ? {} : tmp1;
6485
+ var _args__split = _sliced_to_array(args[0].split(':'), 2), eventType = _args__split[0], eventModifier = _args__split[1];
6486
+ var attribute = typeof attr === 'string' ? attr : attr(facetValue);
6487
+ if (args.length === 1 && _type_of(args[0]) === 'object') {
6488
+ instantSearchInstance.sendEventToInsights(args[0]);
6489
+ } else if (eventType === 'click' && args.length >= 2 && args.length <= 4) {
6490
+ if (!isFacetRefined(helper, attribute, facetValue)) {
6491
+ var _helper_lastResults;
6492
+ // send event only when the facet is being checked "ON"
6493
+ instantSearchInstance.sendEventToInsights({
6494
+ insightsMethod: 'clickedFilters',
6495
+ widgetType: widgetType,
6496
+ eventType: eventType,
6497
+ eventModifier: eventModifier,
6498
+ payload: _object_spread({
6499
+ eventName: eventName,
6500
+ index: ((_helper_lastResults = helper.lastResults) === null || _helper_lastResults === void 0 ? void 0 : _helper_lastResults.index) || helper.state.index,
6501
+ filters: [
6502
+ "".concat(attribute, ":").concat(facetValue)
6503
+ ]
6504
+ }, additionalData),
6505
+ attribute: attribute
6506
+ });
6507
+ }
6508
+ } else ;
6509
+ };
6510
+ return sendEventForFacet;
6511
+ }
6512
+
6513
+ function serializePayload(payload) {
6514
+ return btoa(encodeURIComponent(JSON.stringify(payload)));
6515
+ }
6516
+
6517
+ function chunk(arr) {
6518
+ var chunkSize = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 20;
6519
+ var chunks = [];
6520
+ for(var i = 0; i < Math.ceil(arr.length / chunkSize); i++){
6521
+ chunks.push(arr.slice(i * chunkSize, (i + 1) * chunkSize));
6522
+ }
6523
+ return chunks;
6524
+ }
6525
+ function _buildEventPayloadsForHits(param) {
6526
+ var helper = param.helper, widgetType = param.widgetType;
6527
+ param.methodName;
6528
+ var args = param.args, instantSearchInstance = param.instantSearchInstance;
6529
+ // when there's only one argument, that means it's custom
6530
+ if (args.length === 1 && _type_of(args[0]) === 'object') {
6531
+ return [
6532
+ args[0]
6533
+ ];
6534
+ }
6535
+ var _args__split = _sliced_to_array(args[0].split(':'), 2), eventType = _args__split[0], eventModifier = _args__split[1];
6536
+ var hits = args[1];
6537
+ var eventName = args[2];
6538
+ var additionalData = args[3] || {};
6539
+ if (!hits) {
6540
+ {
6541
+ return [];
6542
+ }
6543
+ }
6544
+ if ((eventType === 'click' || eventType === 'conversion') && !eventName) {
6545
+ {
6546
+ return [];
6547
+ }
6548
+ }
6549
+ var hitsArray = Array.isArray(hits) ? hits : [
6550
+ hits
6551
+ ];
6552
+ if (hitsArray.length === 0) {
6553
+ return [];
6554
+ }
6555
+ var queryID = hitsArray[0].__queryID;
6556
+ var hitsChunks = chunk(hitsArray);
6557
+ var objectIDsByChunk = hitsChunks.map(function(batch) {
6558
+ return batch.map(function(hit) {
6559
+ return hit.objectID;
6560
+ });
6561
+ });
6562
+ var positionsByChunk = hitsChunks.map(function(batch) {
6563
+ return batch.map(function(hit) {
6564
+ return hit.__position;
6565
+ });
6566
+ });
6567
+ if (eventType === 'view') {
6568
+ if (instantSearchInstance.status !== 'idle') {
6569
+ return [];
6570
+ }
6571
+ return hitsChunks.map(function(batch, i) {
6572
+ var _helper_lastResults;
6573
+ return {
6574
+ insightsMethod: 'viewedObjectIDs',
6575
+ widgetType: widgetType,
6576
+ eventType: eventType,
6577
+ payload: _object_spread({
6578
+ eventName: eventName || 'Hits Viewed',
6579
+ index: ((_helper_lastResults = helper.lastResults) === null || _helper_lastResults === void 0 ? void 0 : _helper_lastResults.index) || helper.state.index,
6580
+ objectIDs: objectIDsByChunk[i]
6581
+ }, additionalData),
6582
+ hits: batch,
6583
+ eventModifier: eventModifier
6584
+ };
6585
+ });
6586
+ } else if (eventType === 'click') {
6587
+ return hitsChunks.map(function(batch, i) {
6588
+ var _helper_lastResults;
6589
+ return {
6590
+ insightsMethod: 'clickedObjectIDsAfterSearch',
6591
+ widgetType: widgetType,
6592
+ eventType: eventType,
6593
+ payload: _object_spread({
6594
+ eventName: eventName || 'Hit Clicked',
6595
+ index: ((_helper_lastResults = helper.lastResults) === null || _helper_lastResults === void 0 ? void 0 : _helper_lastResults.index) || helper.state.index,
6596
+ queryID: queryID,
6597
+ objectIDs: objectIDsByChunk[i],
6598
+ positions: positionsByChunk[i]
6599
+ }, additionalData),
6600
+ hits: batch,
6601
+ eventModifier: eventModifier
6602
+ };
6603
+ });
6604
+ } else if (eventType === 'conversion') {
6605
+ return hitsChunks.map(function(batch, i) {
6606
+ var _helper_lastResults;
6607
+ return {
6608
+ insightsMethod: 'convertedObjectIDsAfterSearch',
6609
+ widgetType: widgetType,
6610
+ eventType: eventType,
6611
+ payload: _object_spread({
6612
+ eventName: eventName || 'Hit Converted',
6613
+ index: ((_helper_lastResults = helper.lastResults) === null || _helper_lastResults === void 0 ? void 0 : _helper_lastResults.index) || helper.state.index,
6614
+ queryID: queryID,
6615
+ objectIDs: objectIDsByChunk[i]
6616
+ }, additionalData),
6617
+ hits: batch,
6618
+ eventModifier: eventModifier
6619
+ };
6620
+ });
6621
+ } else {
6622
+ return [];
6623
+ }
6624
+ }
6625
+ function createSendEventForHits(param) {
6626
+ var instantSearchInstance = param.instantSearchInstance, helper = param.helper, widgetType = param.widgetType;
6627
+ var sentEvents = {};
6628
+ var timer = undefined;
6629
+ var sendEventForHits = function sendEventForHits() {
6630
+ for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
6631
+ args[_key] = arguments[_key];
6632
+ }
6633
+ var payloads = _buildEventPayloadsForHits({
6634
+ widgetType: widgetType,
6635
+ helper: helper,
6636
+ methodName: 'sendEvent',
6637
+ args: args,
6638
+ instantSearchInstance: instantSearchInstance
6639
+ });
6640
+ payloads.forEach(function(payload) {
6641
+ if (payload.eventType === 'click' && payload.eventModifier === 'internal' && sentEvents[payload.eventType]) {
6642
+ return;
6643
+ }
6644
+ sentEvents[payload.eventType] = true;
6645
+ instantSearchInstance.sendEventToInsights(payload);
6646
+ });
6647
+ clearTimeout(timer);
6648
+ timer = setTimeout(function() {
6649
+ sentEvents = {};
6650
+ }, 0);
6651
+ };
6652
+ return sendEventForHits;
6653
+ }
6654
+ function createBindEventForHits(param) {
6655
+ var helper = param.helper, widgetType = param.widgetType, instantSearchInstance = param.instantSearchInstance;
6656
+ var bindEventForHits = function bindEventForHits() {
6657
+ for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
6658
+ args[_key] = arguments[_key];
6659
+ }
6660
+ var payloads = _buildEventPayloadsForHits({
6661
+ widgetType: widgetType,
6662
+ helper: helper,
6663
+ methodName: 'bindEvent',
6664
+ args: args,
6665
+ instantSearchInstance: instantSearchInstance
6666
+ });
6667
+ return payloads.length ? "data-insights-event=".concat(serializePayload(payloads)) : '';
6668
+ };
6669
+ return bindEventForHits;
6670
+ }
6671
+
6672
+ var indexWidgetTypes = [
6673
+ 'ais.index',
6674
+ 'ais.feedContainer'
6675
+ ];
6676
+
6677
+ function isIndexWidget(widget) {
6678
+ return indexWidgetTypes.includes(widget.$$type);
6679
+ }
6680
+
6681
+ function setIndexHelperState(finalUiState, indexWidget) {
6682
+ var nextIndexUiState = finalUiState[indexWidget.getIndexId()] || {};
6683
+ indexWidget.getHelper().setState(indexWidget.getWidgetSearchParameters(indexWidget.getHelper().state, {
6684
+ uiState: nextIndexUiState
6685
+ }));
6686
+ indexWidget.getWidgets().filter(isIndexWidget).forEach(function(widget) {
6687
+ return setIndexHelperState(finalUiState, widget);
6688
+ });
6689
+ }
6690
+
6691
+ var nextMicroTask = Promise.resolve();
6692
+ function defer(callback) {
6693
+ var progress = null;
6694
+ var cancelled = false;
6695
+ var fn = function fn() {
6696
+ for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
6697
+ args[_key] = arguments[_key];
6698
+ }
6699
+ if (progress !== null) {
6700
+ return;
6701
+ }
6702
+ progress = nextMicroTask.then(function() {
6703
+ progress = null;
6704
+ if (cancelled) {
6705
+ cancelled = false;
6706
+ return;
6707
+ }
6708
+ callback.apply(void 0, _to_consumable_array(args));
6709
+ });
6710
+ };
6711
+ fn.wait = function() {
6712
+ if (progress === null) {
6713
+ throw new Error('The deferred function should be called before calling `wait()`');
6714
+ }
6715
+ return progress;
6716
+ };
6717
+ fn.cancel = function() {
6718
+ if (progress === null) {
6719
+ return;
6720
+ }
6721
+ cancelled = true;
6722
+ };
6723
+ return fn;
6724
+ }
6725
+
6726
+ function sendChatMessageFeedback(param) {
6727
+ var agentId = param.agentId, vote = param.vote, messageId = param.messageId, appId = param.appId, apiKey = param.apiKey;
6728
+ return fetch("https://".concat(appId, ".algolia.net/agent-studio/1/feedback"), {
6729
+ method: 'POST',
6730
+ body: JSON.stringify({
6731
+ messageId: messageId,
6732
+ agentId: agentId,
6733
+ vote: vote
6734
+ }),
6735
+ headers: {
6736
+ 'x-algolia-application-id': appId,
6737
+ 'x-algolia-api-key': apiKey,
6738
+ 'content-type': 'application/json'
6739
+ }
6740
+ }).then(function(response) {
6741
+ if (response.status >= 300) {
6742
+ return response.json().then(function(data) {
6743
+ throw new Error("Feedback request failed with status ".concat(response.status, ": ").concat(data.message));
6744
+ });
6745
+ }
6746
+ return response.json();
6747
+ });
6748
+ }
6749
+
6750
+ function unescapeFacetValue(value) {
6751
+ if (typeof value === 'string') {
6752
+ return value.replace(/^\\-/, '-');
6753
+ }
6754
+ return value;
6755
+ }
6756
+ function escapeFacetValue(value) {
6757
+ if (typeof value === 'number' && value < 0 || typeof value === 'string') {
6758
+ return String(value).replace(/^-/, '\\-');
6759
+ }
6760
+ return value;
6761
+ }
6762
+
6763
+ // We aren't using the native `Array.prototype.find` because the refactor away from Lodash is not
6764
+ // published as a major version.
6765
+ // Relying on the `find` polyfill on user-land, which before was only required for niche use-cases,
6766
+ // was decided as too risky.
6767
+ // @MAJOR Replace with the native `Array.prototype.find` method
6768
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
6769
+ function find(items, predicate) {
6770
+ var value;
6771
+ for(var i = 0; i < items.length; i++){
6772
+ value = items[i];
6773
+ // inlined for performance: if (Call(predicate, thisArg, [value, i, list])) {
6774
+ if (predicate(value, i, items)) {
6775
+ return value;
6776
+ }
6777
+ }
6778
+ return undefined;
6779
+ }
6780
+
6781
+ var latLngRegExp = /^(-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)$/;
6782
+ function aroundLatLngToPosition(value) {
6783
+ var pattern = value.match(latLngRegExp);
6784
+ // Since the value provided is the one send with the request, the API should
6785
+ // throw an error due to the wrong format. So throw an error should be safe.
6786
+ if (!pattern) {
6787
+ throw new Error('Invalid value for "aroundLatLng" parameter: "'.concat(value, '"'));
6788
+ }
6789
+ return {
6790
+ lat: parseFloat(pattern[1]),
6791
+ lng: parseFloat(pattern[2])
6792
+ };
6793
+ }
6794
+ function insideBoundingBoxArrayToBoundingBox(value) {
6795
+ var _value = _sliced_to_array(value, 1), tmp = _value[0], _ref = _sliced_to_array(tmp === void 0 ? [
6796
+ undefined,
6797
+ undefined,
6798
+ undefined,
6799
+ undefined
6800
+ ] : tmp, 4), neLat = _ref[0], neLng = _ref[1], swLat = _ref[2], swLng = _ref[3];
6801
+ // Since the value provided is the one send with the request, the API should
6802
+ // throw an error due to the wrong format. So throw an error should be safe.
6803
+ if (!neLat || !neLng || !swLat || !swLng) {
6804
+ throw new Error('Invalid value for "insideBoundingBox" parameter: ['.concat(value, "]"));
6805
+ }
6806
+ return {
6807
+ northEast: {
6808
+ lat: neLat,
6809
+ lng: neLng
6810
+ },
6811
+ southWest: {
6812
+ lat: swLat,
6813
+ lng: swLng
6814
+ }
6815
+ };
6816
+ }
6817
+ function insideBoundingBoxStringToBoundingBox(value) {
6818
+ var _value_split_map = _sliced_to_array(value.split(',').map(parseFloat), 4), neLat = _value_split_map[0], neLng = _value_split_map[1], swLat = _value_split_map[2], swLng = _value_split_map[3];
6819
+ // Since the value provided is the one send with the request, the API should
6820
+ // throw an error due to the wrong format. So throw an error should be safe.
6821
+ if (!neLat || !neLng || !swLat || !swLng) {
6822
+ throw new Error('Invalid value for "insideBoundingBox" parameter: "'.concat(value, '"'));
6823
+ }
6824
+ return {
6825
+ northEast: {
6826
+ lat: neLat,
6827
+ lng: neLng
6828
+ },
6829
+ southWest: {
6830
+ lat: swLat,
6831
+ lng: swLng
6832
+ }
6833
+ };
6834
+ }
6835
+ function insideBoundingBoxToBoundingBox(value) {
6836
+ if (Array.isArray(value)) {
6837
+ return insideBoundingBoxArrayToBoundingBox(value);
6838
+ }
6839
+ return insideBoundingBoxStringToBoundingBox(value);
6840
+ }
6841
+
6842
+ function getAlgoliaAgent(client) {
6843
+ var clientTyped = client;
6844
+ return clientTyped.transporter && clientTyped.transporter.userAgent ? clientTyped.transporter.userAgent.value : clientTyped._ua;
6845
+ }
6846
+
6847
+ // typed as any, since it accepts the _real_ js clients, not the interface we otherwise expect
6848
+ function getAppIdAndApiKey(searchClient) {
6849
+ if (searchClient.appId && searchClient.apiKey) {
6850
+ // searchClient v5
6851
+ return [
6852
+ searchClient.appId,
6853
+ searchClient.apiKey
6854
+ ];
6855
+ } else if (searchClient.transporter) {
6856
+ // searchClient v4 or v5
6857
+ var transporter = searchClient.transporter;
6858
+ var headers = transporter.headers || transporter.baseHeaders;
6859
+ var queryParameters = transporter.queryParameters || transporter.baseQueryParameters;
6860
+ var APP_ID = 'x-algolia-application-id';
6861
+ var API_KEY = 'x-algolia-api-key';
6862
+ var appId = headers[APP_ID] || queryParameters[APP_ID];
6863
+ var apiKey = headers[API_KEY] || queryParameters[API_KEY];
6864
+ return [
6865
+ appId,
6866
+ apiKey
6867
+ ];
6868
+ } else {
6869
+ // searchClient v3
6870
+ return [
6871
+ searchClient.applicationID,
6872
+ searchClient.apiKey
6873
+ ];
6874
+ }
6875
+ }
6876
+
6877
+ function getHighlightedParts(highlightedValue) {
6878
+ // @MAJOR: this should use TAG_PLACEHOLDER
6879
+ var highlightPostTag = TAG_REPLACEMENT.highlightPostTag, highlightPreTag = TAG_REPLACEMENT.highlightPreTag;
6880
+ var splitByPreTag = highlightedValue.split(highlightPreTag);
6881
+ var firstValue = splitByPreTag.shift();
6882
+ var elements = !firstValue ? [] : [
6883
+ {
6884
+ value: firstValue,
6885
+ isHighlighted: false
6886
+ }
6887
+ ];
6888
+ splitByPreTag.forEach(function(split) {
6889
+ var splitByPostTag = split.split(highlightPostTag);
6890
+ elements.push({
6891
+ value: splitByPostTag[0],
6892
+ isHighlighted: true
6893
+ });
6894
+ if (splitByPostTag[1] !== '') {
6895
+ elements.push({
6896
+ value: splitByPostTag[1],
6897
+ isHighlighted: false
6898
+ });
6899
+ }
6900
+ });
6901
+ return elements;
6902
+ }
6903
+
6904
+ var hasAlphanumeric = new RegExp(/\w/i);
6905
+ function getHighlightFromSiblings(parts, i) {
6906
+ var _parts_, _parts_1;
6907
+ var current = parts[i];
6908
+ var isNextHighlighted = ((_parts_ = parts[i + 1]) === null || _parts_ === void 0 ? void 0 : _parts_.isHighlighted) || true;
6909
+ var isPreviousHighlighted = ((_parts_1 = parts[i - 1]) === null || _parts_1 === void 0 ? void 0 : _parts_1.isHighlighted) || true;
6910
+ if (!hasAlphanumeric.test(unescape$1(current.value)) && isPreviousHighlighted === isNextHighlighted) {
6911
+ return isPreviousHighlighted;
6912
+ }
6913
+ return current.isHighlighted;
6914
+ }
6915
+
6916
+ function getPropertyByPath(object, path) {
6917
+ var parts = Array.isArray(path) ? path : path.split('.');
6918
+ return parts.reduce(function(current, key) {
6919
+ return current && current[key];
6920
+ }, object);
6921
+ }
6922
+
6923
+ function getRefinement(state, type, attribute, name) {
6924
+ var resultsFacets = arguments.length > 4 && arguments[4] !== void 0 ? arguments[4] : [];
6925
+ var res = {
6926
+ type: type,
6927
+ attribute: attribute,
6928
+ name: name,
6929
+ escapedValue: escapeFacetValue(name)
6930
+ };
6931
+ var facet = find(resultsFacets, function(resultsFacet) {
6932
+ return resultsFacet.name === attribute;
6933
+ });
6934
+ var count;
6935
+ if (type === 'hierarchical') {
6936
+ var _loop = function _loop(i) {
6937
+ facet = facet && facet.data && find(Object.keys(facet.data).map(getFacetRefinement(facet.data)), function(refinement) {
6938
+ return refinement.name === nameParts[i];
6939
+ });
6940
+ };
6941
+ var facetDeclaration = state.getHierarchicalFacetByName(attribute);
6942
+ var nameParts = name.split(facetDeclaration.separator);
6943
+ var getFacetRefinement = function getFacetRefinement(facetData) {
6944
+ return function(refinementKey) {
6945
+ return facetData[refinementKey];
6946
+ };
6947
+ };
6948
+ for(var i = 0; facet !== undefined && i < nameParts.length; ++i)_loop(i);
6949
+ count = facet && facet.count;
6950
+ } else {
6951
+ count = facet && facet.data && facet.data[res.name];
6952
+ }
6953
+ if (count !== undefined) {
6954
+ res.count = count;
6955
+ }
6956
+ if (facet && facet.exhaustive !== undefined) {
6957
+ res.exhaustive = facet.exhaustive;
6958
+ }
6959
+ return res;
6960
+ }
6961
+ function getRefinements(_results, state) {
6962
+ var includesQuery = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : false;
6963
+ var results = _results || {};
6964
+ var refinements = [];
6965
+ var _state_facetsRefinements = state.facetsRefinements, facetsRefinements = _state_facetsRefinements === void 0 ? {} : _state_facetsRefinements, _state_facetsExcludes = state.facetsExcludes, facetsExcludes = _state_facetsExcludes === void 0 ? {} : _state_facetsExcludes, _state_disjunctiveFacetsRefinements = state.disjunctiveFacetsRefinements, disjunctiveFacetsRefinements = _state_disjunctiveFacetsRefinements === void 0 ? {} : _state_disjunctiveFacetsRefinements, _state_hierarchicalFacetsRefinements = state.hierarchicalFacetsRefinements, hierarchicalFacetsRefinements = _state_hierarchicalFacetsRefinements === void 0 ? {} : _state_hierarchicalFacetsRefinements, _state_numericRefinements = state.numericRefinements, numericRefinements = _state_numericRefinements === void 0 ? {} : _state_numericRefinements, _state_tagRefinements = state.tagRefinements, tagRefinements = _state_tagRefinements === void 0 ? [] : _state_tagRefinements;
6966
+ Object.keys(facetsRefinements).forEach(function(attribute) {
6967
+ var refinementNames = facetsRefinements[attribute];
6968
+ refinementNames.forEach(function(refinementName) {
6969
+ refinements.push(getRefinement(state, 'facet', attribute, refinementName, results.facets));
6970
+ });
6971
+ });
6972
+ Object.keys(facetsExcludes).forEach(function(attribute) {
6973
+ var refinementNames = facetsExcludes[attribute];
6974
+ refinementNames.forEach(function(refinementName) {
6975
+ refinements.push({
6976
+ type: 'exclude',
6977
+ attribute: attribute,
6978
+ name: refinementName,
6979
+ exclude: true
6980
+ });
6981
+ });
6982
+ });
6983
+ Object.keys(disjunctiveFacetsRefinements).forEach(function(attribute) {
6984
+ var refinementNames = disjunctiveFacetsRefinements[attribute];
6985
+ refinementNames.forEach(function(refinementName) {
6986
+ refinements.push(getRefinement(state, 'disjunctive', attribute, // they can be escaped on negative numeric values with `escapeFacetValue`.
6987
+ unescapeFacetValue(refinementName), results.disjunctiveFacets));
6988
+ });
6989
+ });
6990
+ Object.keys(hierarchicalFacetsRefinements).forEach(function(attribute) {
6991
+ var refinementNames = hierarchicalFacetsRefinements[attribute];
6992
+ refinementNames.forEach(function(refinement) {
6993
+ refinements.push(getRefinement(state, 'hierarchical', attribute, refinement, results.hierarchicalFacets));
6994
+ });
6995
+ });
6996
+ Object.keys(numericRefinements).forEach(function(attribute) {
6997
+ var operators = numericRefinements[attribute];
6998
+ Object.keys(operators).forEach(function(operatorOriginal) {
6999
+ var operator = operatorOriginal;
7000
+ var valueOrValues = operators[operator];
7001
+ var refinementNames = Array.isArray(valueOrValues) ? valueOrValues : [
7002
+ valueOrValues
7003
+ ];
7004
+ refinementNames.forEach(function(refinementName) {
7005
+ refinements.push({
7006
+ type: 'numeric',
7007
+ attribute: attribute,
7008
+ name: "".concat(refinementName),
7009
+ numericValue: refinementName,
7010
+ operator: operator
7011
+ });
7012
+ });
7013
+ });
7014
+ });
7015
+ tagRefinements.forEach(function(refinementName) {
7016
+ refinements.push({
7017
+ type: 'tag',
7018
+ attribute: '_tags',
7019
+ name: refinementName
7020
+ });
7021
+ });
7022
+ if (includesQuery && state.query && state.query.trim()) {
7023
+ refinements.push({
7024
+ attribute: 'query',
7025
+ type: 'query',
7026
+ name: state.query,
7027
+ query: state.query
7028
+ });
7029
+ }
7030
+ return refinements;
7031
+ }
7032
+
7033
+ function getWidgetAttribute$1(widget, initOptions) {
7034
+ var _widget_getWidgetRenderState;
7035
+ var renderState = (_widget_getWidgetRenderState = widget.getWidgetRenderState) === null || _widget_getWidgetRenderState === void 0 ? void 0 : _widget_getWidgetRenderState.call(widget, initOptions);
7036
+ var attribute = null;
7037
+ if (renderState && renderState.widgetParams) {
7038
+ // casting as widgetParams is checked just before
7039
+ var widgetParams = renderState.widgetParams;
7040
+ if (widgetParams.attribute) {
7041
+ attribute = widgetParams.attribute;
7042
+ } else if (Array.isArray(widgetParams.attributes)) {
7043
+ attribute = widgetParams.attributes[0];
7044
+ }
7045
+ }
7046
+ if (typeof attribute !== 'string') {
7047
+ throw new Error("Could not find the attribute of the widget:\n\n".concat(JSON.stringify(widget), "\n\nPlease check whether the widget's getWidgetRenderState returns widgetParams.attribute correctly."));
7048
+ }
7049
+ return attribute;
7050
+ }
7051
+
7052
+ function addAbsolutePosition(hits, page, hitsPerPage) {
7053
+ return hits.map(function(hit, idx) {
7054
+ return _object_spread_props(_object_spread({}, hit), {
7055
+ __position: hitsPerPage * page + idx + 1
7056
+ });
7057
+ });
7058
+ }
7059
+
7060
+ function addQueryID(hits, queryID) {
7061
+ if (!queryID) {
7062
+ return hits;
7063
+ }
7064
+ return hits.map(function(hit) {
7065
+ return _object_spread_props(_object_spread({}, hit), {
7066
+ __queryID: queryID
7067
+ });
7068
+ });
7069
+ }
7070
+
7071
+ function hydrateRecommendCache(helper, initialResults) {
7072
+ var recommendCache = Object.keys(initialResults).reduce(function(acc, indexName) {
7073
+ var initialResult = initialResults[indexName];
7074
+ if (initialResult.recommendResults) {
7075
+ // @MAJOR: Use `Object.assign` instead of spread operator
7076
+ return _object_spread({}, acc, initialResult.recommendResults.results);
7077
+ }
7078
+ return acc;
7079
+ }, {});
7080
+ helper._recommendCache = recommendCache;
7081
+ }
7082
+
7083
+ function getServerResults(entry) {
7084
+ var _entry_compositionFeedsResults;
7085
+ return ((_entry_compositionFeedsResults = entry.compositionFeedsResults) === null || _entry_compositionFeedsResults === void 0 ? void 0 : _entry_compositionFeedsResults.length) ? entry.compositionFeedsResults : entry.results || [];
7086
+ }
7087
+ function hydrateSearchClient(client, results) {
7088
+ if (!results) {
7089
+ return;
7090
+ }
7091
+ // Disable cache hydration on:
7092
+ // - Algoliasearch API Client < v4 with cache disabled
7093
+ // - Third party clients (detected by the `addAlgoliaAgent` function missing)
7094
+ if ((!('transporter' in client) || client._cacheHydrated) && (!client._useCache || typeof client.addAlgoliaAgent !== 'function')) {
7095
+ return;
7096
+ }
7097
+ var cachedRequest = [
7098
+ Object.keys(results).reduce(function(acc, key) {
7099
+ var entry = results[key];
7100
+ var state = entry.state, requestParams = entry.requestParams;
7101
+ var serverResults = getServerResults(entry);
7102
+ var mappedResults = serverResults && state ? serverResults.map(function(result, idx) {
7103
+ return _object_spread({
7104
+ indexName: state.index || result.index
7105
+ }, (requestParams === null || requestParams === void 0 ? void 0 : requestParams[idx]) || result.params ? {
7106
+ params: serializeQueryParameters((requestParams === null || requestParams === void 0 ? void 0 : requestParams[idx]) || deserializeQueryParameters(result.params))
7107
+ } : {});
7108
+ }) : [];
7109
+ return acc.concat(mappedResults);
7110
+ }, [])
7111
+ ];
7112
+ var cachedResults = Object.keys(results).reduce(function(acc, key) {
7113
+ var res = getServerResults(results[key]);
7114
+ if (!res) {
7115
+ return acc;
7116
+ }
7117
+ return acc.concat(res);
7118
+ }, []);
7119
+ // Algoliasearch API Client >= v4
7120
+ // To hydrate the client we need to populate the cache with the data from
7121
+ // the server (done in `hydrateSearchClientWithMultiIndexRequest` or
7122
+ // `hydrateSearchClientWithSingleIndexRequest`). But since there is no way
7123
+ // for us to compute the key the same way as `algoliasearch-client` we need
7124
+ // to populate it on a custom key and override the `search` method to
7125
+ // search on it first.
7126
+ if ('transporter' in client && !client._cacheHydrated) {
7127
+ client._cacheHydrated = true;
7128
+ var baseMethod = client.search.bind(client);
7129
+ client.search = function(requests) {
7130
+ for(var _len = arguments.length, methodArgs = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++){
7131
+ methodArgs[_key - 1] = arguments[_key];
7132
+ }
7133
+ var requestsWithSerializedParams = Array.isArray(requests) ? requests.map(function(request) {
7134
+ return _object_spread_props(_object_spread({}, request), {
7135
+ params: serializeQueryParameters(request.params)
7136
+ });
7137
+ }) : serializeQueryParameters(requests.requestBody.params);
7138
+ return client.transporter.responsesCache.get({
7139
+ method: 'search',
7140
+ args: [
7141
+ requestsWithSerializedParams
7142
+ ].concat(_to_consumable_array(methodArgs))
7143
+ }, function() {
7144
+ return baseMethod.apply(void 0, [
7145
+ requests
7146
+ ].concat(_to_consumable_array(methodArgs)));
7147
+ });
7148
+ };
7149
+ client.transporter.responsesCache.set({
7150
+ method: 'search',
7151
+ args: cachedRequest
7152
+ }, {
7153
+ results: cachedResults
7154
+ });
7155
+ }
7156
+ // Algoliasearch API Client < v4
7157
+ // Prior to client v4 we didn't have a proper API to hydrate the client
7158
+ // cache from the outside. The following code populates the cache with
7159
+ // a single-index result. You can find more information about the
7160
+ // computation of the key inside the client (see link below).
7161
+ // https://github.com/algolia/algoliasearch-client-javascript/blob/c27e89ff92b2a854ae6f40dc524bffe0f0cbc169/src/AlgoliaSearchCore.js#L232-L240
7162
+ if (!('transporter' in client)) {
7163
+ var cacheKey = "/1/indexes/*/queries_body_".concat(JSON.stringify({
7164
+ requests: cachedRequest
7165
+ }));
7166
+ client.cache = _object_spread_props(_object_spread({}, client.cache), _define_property({}, cacheKey, JSON.stringify({
7167
+ results: Object.keys(results).map(function(key) {
7168
+ return getServerResults(results[key]);
7169
+ })
7170
+ })));
7171
+ }
7172
+ }
7173
+ function deserializeQueryParameters(parameters) {
7174
+ return parameters.split('&').reduce(function(acc, parameter) {
7175
+ var _parameter_split = _sliced_to_array(parameter.split('='), 2), key = _parameter_split[0], value = _parameter_split[1];
7176
+ acc[key] = value ? decodeURIComponent(value) : '';
7177
+ return acc;
7178
+ }, {});
7179
+ }
7180
+ // This function is copied from the algoliasearch v4 API Client. If modified,
7181
+ // consider updating it also in `serializeQueryParameters` from `@algolia/transporter`.
7182
+ function serializeQueryParameters(parameters) {
7183
+ var isObjectOrArray = function isObjectOrArray(value) {
7184
+ return Object.prototype.toString.call(value) === '[object Object]' || Object.prototype.toString.call(value) === '[object Array]';
7185
+ };
7186
+ var encode = function encode(format) {
7187
+ for(var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++){
7188
+ args[_key - 1] = arguments[_key];
7189
+ }
7190
+ var i = 0;
7191
+ return format.replace(/%s/g, function() {
7192
+ return encodeURIComponent(args[i++]);
7193
+ });
7194
+ };
7195
+ return Object.keys(parameters).map(function(key) {
7196
+ return encode('%s=%s', key, isObjectOrArray(parameters[key]) ? JSON.stringify(parameters[key]) : parameters[key]);
7197
+ }).join('&');
7198
+ }
7199
+
7200
+ function isPrimitive(obj) {
7201
+ return obj !== Object(obj);
7202
+ }
7203
+ function isEqual(first, second) {
7204
+ if (first === second) {
7205
+ return true;
7206
+ }
7207
+ if (isPrimitive(first) || isPrimitive(second) || typeof first === 'function' || typeof second === 'function') {
7208
+ return first === second;
7209
+ }
7210
+ if (Object.keys(first).length !== Object.keys(second).length) {
7211
+ return false;
7212
+ }
7213
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
7214
+ try {
7215
+ // @TODO avoid for..of because of the large polyfill
7216
+ // eslint-disable-next-line instantsearch/no-for-of
7217
+ for(var _iterator = Object.keys(first)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
7218
+ var key = _step.value;
7219
+ if (!(key in second)) {
7220
+ return false;
7221
+ }
7222
+ if (!isEqual(first[key], second[key])) {
7223
+ return false;
7224
+ }
7225
+ }
7226
+ } catch (err) {
7227
+ _didIteratorError = true;
7228
+ _iteratorError = err;
7229
+ } finally{
7230
+ try {
7231
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
7232
+ _iterator.return();
7233
+ }
7234
+ } finally{
7235
+ if (_didIteratorError) {
7236
+ throw _iteratorError;
7237
+ }
7238
+ }
7239
+ }
7240
+ return true;
7241
+ }
7242
+
7243
+ // This is the `Number.isFinite()` polyfill recommended by MDN.
7244
+ // We do not provide any tests for this function.
7245
+ // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite#Polyfill
7246
+ // @MAJOR Replace with the native `Number.isFinite` method
7247
+ function isFiniteNumber(value) {
7248
+ return typeof value === 'number' && isFinite(value);
7249
+ }
7250
+
7251
+ /**
7252
+ * Recurse over all child indices
7253
+ */ function walkIndex(indexWidget, callback) {
7254
+ callback(indexWidget);
7255
+ indexWidget.getWidgets().forEach(function(widget) {
7256
+ if (isIndexWidget(widget)) {
7257
+ walkIndex(widget, callback);
7258
+ }
7259
+ });
7260
+ }
7261
+
7262
+ /**
7263
+ * Returns true if the widget requires a second SSR pass to discover and
7264
+ * mount child widgets (e.g. DynamicWidgets, Feeds).
7265
+ */ function isTwoPassWidget(widget) {
7266
+ return widget.$$type === 'ais.dynamicWidgets' || widget.$$type === 'ais.feeds';
7267
+ }
7268
+
7269
+ function range(param) {
7270
+ var _param_start = param.start, start = _param_start === void 0 ? 0 : _param_start, end = param.end, _param_step = param.step, step = _param_step === void 0 ? 1 : _param_step;
7271
+ // We can't divide by 0 so we re-assign the step to 1 if it happens.
7272
+ var limitStep = step === 0 ? 1 : step;
7273
+ // In some cases the array to create has a decimal length.
7274
+ // We therefore need to round the value.
7275
+ // Example:
7276
+ // { start: 1, end: 5000, step: 500 }
7277
+ // => Array length = (5000 - 1) / 500 = 9.998
7278
+ var arrayLength = Math.round((end - start) / limitStep);
7279
+ return _to_consumable_array(Array(arrayLength)).map(function(_, current) {
7280
+ return start + current * limitStep;
7281
+ });
7282
+ }
7283
+
7284
+ function createInitArgs(instantSearchInstance, parent, uiState) {
7285
+ var helper = parent.getHelper();
7286
+ return {
7287
+ uiState: uiState,
7288
+ helper: helper,
7289
+ parent: parent,
7290
+ instantSearchInstance: instantSearchInstance,
7291
+ state: helper.state,
7292
+ renderState: instantSearchInstance.renderState,
7293
+ templatesConfig: instantSearchInstance.templatesConfig,
7294
+ createURL: parent.createURL,
7295
+ scopedResults: [],
7296
+ searchMetadata: {
7297
+ isSearchStalled: instantSearchInstance.status === 'stalled'
7298
+ },
7299
+ status: instantSearchInstance.status,
7300
+ error: instantSearchInstance.error
7301
+ };
7302
+ }
7303
+ function createRenderArgs(instantSearchInstance, parent, widget) {
7304
+ var results = parent.getResultsForWidget(widget);
7305
+ var helper = parent.getHelper();
7306
+ return {
7307
+ helper: helper,
7308
+ parent: parent,
7309
+ instantSearchInstance: instantSearchInstance,
7310
+ results: results,
7311
+ scopedResults: parent.getScopedResults(),
7312
+ state: results && '_state' in results ? results._state : helper.state,
7313
+ renderState: instantSearchInstance.renderState,
7314
+ templatesConfig: instantSearchInstance.templatesConfig,
7315
+ createURL: parent.createURL,
7316
+ searchMetadata: {
7317
+ isSearchStalled: instantSearchInstance.status === 'stalled'
7318
+ },
7319
+ status: instantSearchInstance.status,
7320
+ error: instantSearchInstance.error
7321
+ };
7322
+ }
7323
+ function storeRenderState(param) {
7324
+ var renderState = param.renderState, instantSearchInstance = param.instantSearchInstance, parent = param.parent;
7325
+ var parentIndexName = parent ? parent.getIndexId() : instantSearchInstance.mainIndex.getIndexId();
7326
+ instantSearchInstance.renderState = _object_spread_props(_object_spread({}, instantSearchInstance.renderState), _define_property({}, parentIndexName, _object_spread({}, instantSearchInstance.renderState[parentIndexName], renderState)));
7327
+ }
7328
+
7329
+ function resolveSearchParameters(current) {
7330
+ var parent = current.getParent();
7331
+ var states = [
7332
+ current.getHelper().state
7333
+ ];
7334
+ while(parent !== null){
7335
+ states = [
7336
+ parent.getHelper().state
7337
+ ].concat(states);
7338
+ parent = parent.getParent();
7339
+ }
7340
+ return states;
7341
+ }
7342
+
7343
+ function reverseHighlightedParts(parts) {
7344
+ if (!parts.some(function(part) {
7345
+ return part.isHighlighted;
7346
+ })) {
7347
+ return parts.map(function(part) {
7348
+ return _object_spread_props(_object_spread({}, part), {
7349
+ isHighlighted: false
7350
+ });
7351
+ });
7352
+ }
7353
+ return parts.map(function(part, i) {
7354
+ return _object_spread_props(_object_spread({}, part), {
7355
+ isHighlighted: !getHighlightFromSiblings(parts, i)
7356
+ });
7357
+ });
7358
+ }
7359
+
7360
+ // eslint-disable-next-line no-restricted-globals
7361
+ /**
7362
+ * Runs code on browser environments safely.
7363
+ */ function safelyRunOnBrowser(callback) {
7364
+ var fallback = (arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {
7365
+ fallback: function fallback() {
7366
+ return undefined;
7367
+ }
7368
+ }).fallback;
7369
+ // eslint-disable-next-line no-restricted-globals
7370
+ if (typeof window === 'undefined') {
7371
+ return fallback();
7372
+ }
7373
+ // eslint-disable-next-line no-restricted-globals
7374
+ return callback({
7375
+ window: window
7376
+ });
7377
+ }
7378
+
7379
+ function toArray(value) {
7380
+ return Array.isArray(value) ? value : [
7381
+ value
7382
+ ];
7383
+ }
7384
+
7385
+ var useKey = 'use';
7386
+ // @TODO: Remove this file and import directly from React when available.
7387
+ var use = React__namespace[useKey];
7388
+
7389
+ /**
7390
+ * `useLayoutEffect` that doesn't show a warning when server-side rendering.
7391
+ *
7392
+ * It uses `useEffect` on the server (no-op), and `useLayoutEffect` on the browser.
7393
+ */ var useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;
7394
+
7395
+ var InstantSearchRSCContext = React.createContext({
7396
+ countRef: {
7397
+ current: 0
7398
+ },
7399
+ waitForResultsRef: null,
7400
+ ignoreMultipleHooksWarning: false
7401
+ });
7402
+
7403
+ function useRSCContext() {
7404
+ return React.useContext(InstantSearchRSCContext);
7405
+ }
7406
+
7407
+ /* eslint-disable no-console, no-empty */ var warnCache = {
7408
+ current: {}
7409
+ };
7410
+ /**
7411
+ * Logs a warning if the condition is not met.
7412
+ * This is used to log issues in development environment only.
7413
+ */ function warn(condition, message) {
7414
+ if (condition) {
7415
+ return;
7416
+ }
7417
+ var sanitizedMessage = message.trim();
7418
+ var hasAlreadyPrinted = warnCache.current[sanitizedMessage];
7419
+ if (!hasAlreadyPrinted) {
7420
+ warnCache.current[sanitizedMessage] = true;
7421
+ var warning = "[InstantSearch] ".concat(sanitizedMessage);
7422
+ console.warn(warning);
7423
+ try {
7424
+ // Welcome to debugging InstantSearch.
7425
+ //
7426
+ // This error was thrown as a convenience so that you can find the source
7427
+ // of the warning that appears in the console by enabling "Pause on exceptions"
7428
+ // in your debugger.
7429
+ throw new Error(warning);
7430
+ } catch (error) {}
7431
+ }
7432
+ }
7433
+
7434
+ function useWidget(param) {
7435
+ var widget = param.widget, parentIndex = param.parentIndex, props = param.props, shouldSsr = param.shouldSsr, skipSuspense = param.skipSuspense;
7436
+ var _waitForResultsRef_current, _waitForResultsRef_current1;
7437
+ var _useRSCContext = useRSCContext(), waitForResultsRef = _useRSCContext.waitForResultsRef, countRef = _useRSCContext.countRef, ignoreMultipleHooksWarning = _useRSCContext.ignoreMultipleHooksWarning;
7438
+ var prevPropsRef = React.useRef(props);
7439
+ React.useEffect(function() {
7440
+ prevPropsRef.current = props;
7441
+ }, [
7442
+ props
7443
+ ]);
7444
+ var prevWidgetRef = React.useRef(widget);
7445
+ React.useEffect(function() {
7446
+ prevWidgetRef.current = widget;
7447
+ }, [
7448
+ widget
7449
+ ]);
7450
+ var cleanupTimerRef = React.useRef(null);
7451
+ var shouldAddWidgetEarly = shouldSsr && !parentIndex.getWidgets().includes(widget);
7452
+ var search = useInstantSearchContext();
7453
+ // This effect is responsible for adding, removing, and updating the widget.
7454
+ // We need to support scenarios where the widget is remounted quickly, like in
7455
+ // Strict Mode, so that we don't lose its state, and therefore that we don't
7456
+ // break routing.
7457
+ useIsomorphicLayoutEffect(function() {
7458
+ var previousWidget = prevWidgetRef.current;
7459
+ // Scenario 1: the widget is added for the first time.
7460
+ if (!cleanupTimerRef.current) {
7461
+ if (!shouldSsr) {
7462
+ parentIndex.addWidgets([
7463
+ widget
7464
+ ]);
7465
+ }
7466
+ } else {
7467
+ // We cancel the original effect cleanup because it may not be necessary if
7468
+ // props haven't changed. (We manually call it if it is below.)
7469
+ clearTimeout(cleanupTimerRef.current);
7470
+ // Warning: if an unstable function prop is provided, `dequal` is not able
7471
+ // to keep its reference and therefore will consider that props did change.
7472
+ // This could unsollicitely remove/add the widget, therefore forget its state,
7473
+ // and could be a source of confusion.
7474
+ // If users face this issue, we should advise them to provide stable function
7475
+ // references.
7476
+ var arePropsEqual = dequal(props, prevPropsRef.current);
7477
+ // If props did change, then we execute the cleanup function instantly
7478
+ // and then add the widget back. This lets us add the widget without
7479
+ // waiting for the scheduled cleanup function to finish (that we canceled
7480
+ // above).
7481
+ if (!arePropsEqual) {
7482
+ parentIndex.removeWidgets([
7483
+ previousWidget
7484
+ ]);
7485
+ parentIndex.addWidgets([
7486
+ widget
7487
+ ]);
7488
+ }
7489
+ }
7490
+ return function() {
7491
+ // We don't remove the widget right away, but rather schedule it so that
7492
+ // we're able to cancel it in the next effect.
7493
+ cleanupTimerRef.current = setTimeout(function() {
7494
+ search._schedule(function() {
7495
+ if (search._preventWidgetCleanup) return;
7496
+ parentIndex.removeWidgets([
7497
+ previousWidget
7498
+ ]);
7499
+ });
7500
+ });
7501
+ };
7502
+ }, [
7503
+ parentIndex,
7504
+ widget,
7505
+ shouldSsr,
7506
+ search,
7507
+ props
7508
+ ]);
7509
+ if (shouldAddWidgetEarly || (waitForResultsRef === null || waitForResultsRef === void 0 ? void 0 : (_waitForResultsRef_current = waitForResultsRef.current) === null || _waitForResultsRef_current === void 0 ? void 0 : _waitForResultsRef_current.status) === 'pending') {
7510
+ parentIndex.addWidgets([
7511
+ widget
7512
+ ]);
7513
+ }
7514
+ if ((waitForResultsRef === null || waitForResultsRef === void 0 ? void 0 : waitForResultsRef.current) && !skipSuspense) {
7515
+ var _search_helper;
7516
+ use(waitForResultsRef.current);
7517
+ // If we made a second request because of two-pass widgets, we need to
7518
+ // wait for the second result — except for the two-pass widgets themselves
7519
+ // which need to render their children after the first result.
7520
+ if (!isTwoPassWidget(widget) && ((_search_helper = search.helper) === null || _search_helper === void 0 ? void 0 : _search_helper.lastResults)) {
7521
+ use(waitForResultsRef.current);
7522
+ }
7523
+ }
7524
+ if ((waitForResultsRef === null || waitForResultsRef === void 0 ? void 0 : (_waitForResultsRef_current1 = waitForResultsRef.current) === null || _waitForResultsRef_current1 === void 0 ? void 0 : _waitForResultsRef_current1.status) === 'fulfilled') {
7525
+ countRef.current += 1;
7526
+ { warn(ignoreMultipleHooksWarning || countRef.current <= parentIndex.getWidgets().length, "We detected you may have a component with multiple InstantSearch hooks.\n\nWith Next.js, you need to set `skipSuspense` to `true` for all but the last hook in the component, otherwise, only the first hook will be rendered on the server.\n\nThis warning can be a false positive if you are using dynamic widgets or multi-index, in which case you can ignore it by setting `ignoreMultipleHooksWarning` to `true` in `<InstantSearchNext`.\n\nFor more information, see https://www.algolia.com/doc/guides/building-search-ui/going-further/server-side-rendering/react/#composing-hooks"); }
7527
+ }
7528
+ }
7529
+
7530
+ function useConnector(connector) {
7531
+ var _1 = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : void 0, _2 = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : void 0;
7532
+ var _ref = [
7533
+ _1,
7534
+ _2
7535
+ ], _ref1 = _to_array(_ref), tmp = _ref1[0], props = tmp === void 0 ? {} : tmp, _rest = _ref1.slice(1), _rest1 = _sliced_to_array(_rest, 1), tmp1 = _rest1[0], _ref2 = tmp1 === void 0 ? {} : tmp1, _ref_skipSuspense = _ref2.skipSuspense, skipSuspense = _ref_skipSuspense === void 0 ? false : _ref_skipSuspense, additionalWidgetProperties = _object_without_properties(_ref2, [
7536
+ "skipSuspense"
7537
+ ]);
7538
+ var serverContext = useInstantSearchServerContext();
7539
+ var ssrContext = useInstantSearchSSRContext();
7540
+ var search = useInstantSearchContext();
7541
+ var parentIndex = useIndexContext();
7542
+ var stableProps = useStableValue(props);
7543
+ var stableAdditionalWidgetProperties = useStableValue(additionalWidgetProperties);
7544
+ var shouldSetStateRef = React.useRef(true);
7545
+ var previousRenderStateRef = React.useRef(null);
7546
+ var previousStatusRef = React.useRef(search.status);
7547
+ var widget = React.useMemo(function() {
7548
+ var createWidget = connector(function(connectorState, isFirstRender) {
7549
+ // We skip the `init` widget render because:
7550
+ // - We rely on `getWidgetRenderState` to compute the initial state before
7551
+ // the InstantSearch.js lifecycle starts.
7552
+ // - It prevents UI flashes when updating the widget props.
7553
+ if (isFirstRender) {
7554
+ shouldSetStateRef.current = true;
7555
+ return;
7556
+ }
7557
+ // There are situations where InstantSearch.js may render widgets slightly
7558
+ // after they're removed by React, and thus try to update the React state
7559
+ // on unmounted components. React 16 and 17 consider them as memory leaks
7560
+ // and display a warning.
7561
+ // This happens in <DynamicWidgets> when `attributesToRender` contains a
7562
+ // value without an attribute previously mounted. React will unmount the
7563
+ // component controlled by that attribute, but InstantSearch.js will stay
7564
+ // unaware of this change until the render pass finishes, and therefore
7565
+ // notifies of a state change.
7566
+ // This ref lets us track this situation and ignore these state updates.
7567
+ if (shouldSetStateRef.current) {
7568
+ var instantSearchInstance = connectorState.instantSearchInstance; connectorState.widgetParams; var renderState = _object_without_properties(connectorState, [
7569
+ "instantSearchInstance",
7570
+ "widgetParams"
7571
+ ]);
7572
+ // We only update the state when a widget render state param changes,
7573
+ // except for functions. We ignore function reference changes to avoid
7574
+ // infinite loops. It's safe to omit them because they get updated
7575
+ // every time another render param changes.
7576
+ if (!dequal(renderState, previousRenderStateRef.current, function(a, b) {
7577
+ return (a === null || a === void 0 ? void 0 : a.constructor) === Function && (b === null || b === void 0 ? void 0 : b.constructor) === Function;
7578
+ }) || instantSearchInstance.status !== previousStatusRef.current) {
7579
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
7580
+ setState(renderState);
7581
+ previousRenderStateRef.current = renderState;
7582
+ previousStatusRef.current = instantSearchInstance.status;
7583
+ }
7584
+ }
7585
+ }, function() {
7586
+ // We'll ignore the next state update until we know for sure that
7587
+ // InstantSearch.js re-inits the component.
7588
+ shouldSetStateRef.current = false;
7589
+ });
7590
+ return _object_spread({}, createWidget(stableProps), stableAdditionalWidgetProperties);
7591
+ }, [
7592
+ connector,
7593
+ stableProps,
7594
+ stableAdditionalWidgetProperties
7595
+ ]);
7596
+ var _useState = _sliced_to_array(React.useState(function() {
7597
+ if (widget.getWidgetRenderState) {
7598
+ var _widget_getWidgetSearchParameters;
7599
+ // The helper exists because we've started InstantSearch.
7600
+ var helper = parentIndex.getHelper();
7601
+ var uiState = parentIndex.getWidgetUiState({})[parentIndex.getIndexId()];
7602
+ helper.state = ((_widget_getWidgetSearchParameters = widget.getWidgetSearchParameters) === null || _widget_getWidgetSearchParameters === void 0 ? void 0 : _widget_getWidgetSearchParameters.call(widget, helper.state, {
7603
+ uiState: uiState
6486
7604
  })) || helper.state;
6487
7605
  var _getIndexSearchResults = getIndexSearchResults(parentIndex), results = _getIndexSearchResults.results, scopedResults = _getIndexSearchResults.scopedResults, recommendResults = _getIndexSearchResults.recommendResults;
6488
7606
  // We get the widget render state by providing the same parameters as
@@ -6533,42 +7651,13 @@
6533
7651
  return null;
6534
7652
  }
6535
7653
 
6536
- function getWidgetAttribute$1(widget, initOptions) {
6537
- var _widget_getWidgetRenderState;
6538
- var renderState = (_widget_getWidgetRenderState = widget.getWidgetRenderState) === null || _widget_getWidgetRenderState === void 0 ? void 0 : _widget_getWidgetRenderState.call(widget, initOptions);
6539
- var attribute = null;
6540
- if (renderState && renderState.widgetParams) {
6541
- // casting as widgetParams is checked just before
6542
- var widgetParams = renderState.widgetParams;
6543
- if (widgetParams.attribute) {
6544
- attribute = widgetParams.attribute;
6545
- } else if (Array.isArray(widgetParams.attributes)) {
6546
- attribute = widgetParams.attributes[0];
6547
- }
6548
- }
6549
- if (typeof attribute !== 'string') {
6550
- throw new Error("Could not find the attribute of the widget:\n\n".concat(JSON.stringify(widget), "\n\nPlease check whether the widget's getWidgetRenderState returns widgetParams.attribute correctly."));
6551
- }
6552
- return attribute;
6553
- }
6554
-
6555
- function getObjectType(object) {
6556
- return Object.prototype.toString.call(object).slice(8, -1);
6557
- }
6558
-
6559
- function checkRendering(rendering, usage) {
6560
- if (rendering === undefined || typeof rendering !== 'function') {
6561
- throw new Error("The render function is not valid (received type ".concat(getObjectType(rendering), ").\n\n").concat(usage));
6562
- }
6563
- }
6564
-
6565
- var withUsage$s = createDocumentationMessageGenerator({
7654
+ var withUsage$t = createDocumentationMessageGenerator({
6566
7655
  name: 'dynamic-widgets',
6567
7656
  connector: true
6568
7657
  });
6569
7658
  var connectDynamicWidgets = function connectDynamicWidgets(renderFn) {
6570
7659
  var unmountFn = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : noop;
6571
- checkRendering(renderFn, withUsage$s());
7660
+ checkRendering(renderFn, withUsage$t());
6572
7661
  return function(widgetParams) {
6573
7662
  var widgets = widgetParams.widgets, _widgetParams_maxValuesPerFacet = widgetParams.maxValuesPerFacet, maxValuesPerFacet = _widgetParams_maxValuesPerFacet === void 0 ? 20 : _widgetParams_maxValuesPerFacet, _widgetParams_facets = widgetParams.facets, facets = _widgetParams_facets === void 0 ? [
6574
7663
  '*'
@@ -6578,10 +7667,10 @@
6578
7667
  if (!(widgets && Array.isArray(widgets) && widgets.every(function(widget) {
6579
7668
  return (typeof widget === "undefined" ? "undefined" : _type_of(widget)) === 'object';
6580
7669
  }))) {
6581
- throw new Error(withUsage$s('The `widgets` option expects an array of widgets.'));
7670
+ throw new Error(withUsage$t('The `widgets` option expects an array of widgets.'));
6582
7671
  }
6583
7672
  if (!Array.isArray(facets)) {
6584
- throw new Error(withUsage$s("The `facets` option only accepts an array of facets, you passed ".concat(JSON.stringify(facets))));
7673
+ throw new Error(withUsage$t("The `facets` option only accepts an array of facets, you passed ".concat(JSON.stringify(facets))));
6585
7674
  }
6586
7675
  var localWidgets = new Map();
6587
7676
  return {
@@ -6683,7 +7772,7 @@
6683
7772
  results: results
6684
7773
  });
6685
7774
  if (!Array.isArray(attributesToRender)) {
6686
- throw new Error(withUsage$s('The `transformItems` option expects a function that returns an Array.'));
7775
+ throw new Error(withUsage$t('The `transformItems` option expects a function that returns an Array.'));
6687
7776
  }
6688
7777
  return {
6689
7778
  attributesToRender: attributesToRender,
@@ -6749,120 +7838,442 @@
6749
7838
  return undefined;
6750
7839
  }
6751
7840
 
6752
- function _array_without_holes(arr) {
6753
- if (Array.isArray(arr)) return _array_like_to_array(arr);
6754
- }
6755
-
6756
- function _non_iterable_spread() {
6757
- throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
7841
+ function createFeedContainer(feedID, parentIndex, instantSearchInstance) {
7842
+ var localWidgets = [];
7843
+ var initialized = false;
7844
+ var container = {
7845
+ $$type: 'ais.feedContainer',
7846
+ $$widgetType: 'ais.feedContainer',
7847
+ _isolated: true,
7848
+ getIndexName: function getIndexName() {
7849
+ return parentIndex.getIndexName();
7850
+ },
7851
+ getIndexId: function getIndexId() {
7852
+ return feedID;
7853
+ },
7854
+ getHelper: function getHelper() {
7855
+ return parentIndex.getHelper();
7856
+ },
7857
+ getResults: function getResults() {
7858
+ var parentResults = parentIndex.getResults();
7859
+ if (!parentResults) return null;
7860
+ if (!parentResults.feeds) {
7861
+ // Single-feed backward compat: no feeds array means the parent result
7862
+ // itself is the only feed.
7863
+ if (feedID === '') {
7864
+ parentResults._state = parentIndex.getHelper().state;
7865
+ return parentResults;
7866
+ }
7867
+ return null;
7868
+ }
7869
+ var feed = parentResults.feeds.find(function(f) {
7870
+ return f.feedID === feedID;
7871
+ });
7872
+ if (!feed) return null;
7873
+ // Optimistic state patching — same as index widget (index.ts:365-370)
7874
+ feed._state = parentIndex.getHelper().state;
7875
+ return feed;
7876
+ },
7877
+ getResultsForWidget: function getResultsForWidget() {
7878
+ return this.getResults();
7879
+ },
7880
+ getParent: function getParent() {
7881
+ return parentIndex;
7882
+ },
7883
+ getWidgets: function getWidgets() {
7884
+ return localWidgets;
7885
+ },
7886
+ getScopedResults: function getScopedResults() {
7887
+ return parentIndex.getScopedResults();
7888
+ },
7889
+ getPreviousState: function getPreviousState() {
7890
+ return null;
7891
+ },
7892
+ createURL: function createURL(nextState) {
7893
+ return parentIndex.createURL(nextState);
7894
+ },
7895
+ scheduleLocalSearch: function scheduleLocalSearch() {
7896
+ return parentIndex.scheduleLocalSearch();
7897
+ },
7898
+ addWidgets: function addWidgets(widgets) {
7899
+ var flatWidgets = widgets.reduce(function(acc, w) {
7900
+ return acc.concat(Array.isArray(w) ? w : [
7901
+ w
7902
+ ]);
7903
+ }, []);
7904
+ flatWidgets.forEach(function(widget) {
7905
+ widget.parent = container;
7906
+ });
7907
+ localWidgets = localWidgets.concat(flatWidgets);
7908
+ if (initialized) {
7909
+ flatWidgets.forEach(function(widget) {
7910
+ if (widget.getRenderState) {
7911
+ var renderState = widget.getRenderState(instantSearchInstance.renderState[container.getIndexId()] || {}, createInitArgs(instantSearchInstance, container, instantSearchInstance._initialUiState));
7912
+ storeRenderState({
7913
+ renderState: renderState,
7914
+ instantSearchInstance: instantSearchInstance,
7915
+ parent: container
7916
+ });
7917
+ }
7918
+ });
7919
+ flatWidgets.forEach(function(widget) {
7920
+ if (widget.init) {
7921
+ widget.init(createInitArgs(instantSearchInstance, container, instantSearchInstance._initialUiState));
7922
+ }
7923
+ });
7924
+ // Merge children's search params (e.g. disjunctiveFacets) into the
7925
+ // parent's helper state so they're included in the composition request.
7926
+ // uiState is {} because URL-derived refinements are already on the
7927
+ // parent state; children only need to declare structural params.
7928
+ var parentHelper = parentIndex.getHelper();
7929
+ var withChildParams = container.getWidgetSearchParameters(parentHelper.state, {
7930
+ uiState: {}
7931
+ });
7932
+ if (withChildParams !== parentHelper.state) {
7933
+ parentHelper.setState(withChildParams);
7934
+ }
7935
+ }
7936
+ return container;
7937
+ },
7938
+ removeWidgets: function removeWidgets(widgets) {
7939
+ var flatWidgets = widgets.reduce(function(acc, w) {
7940
+ return acc.concat(Array.isArray(w) ? w : [
7941
+ w
7942
+ ]);
7943
+ }, []);
7944
+ var helper = parentIndex.getHelper();
7945
+ if (!helper) {
7946
+ localWidgets = localWidgets.filter(function(w) {
7947
+ return !flatWidgets.includes(w);
7948
+ });
7949
+ return container;
7950
+ }
7951
+ // Chain through children's dispose so widgets clean up the
7952
+ // SearchParameters they declared (e.g. RefinementList removes its
7953
+ // disjunctiveFacet) instead of leaving them stale on the parent helper.
7954
+ var cleanedState = helper.state;
7955
+ flatWidgets.forEach(function(widget) {
7956
+ if (widget.dispose) {
7957
+ var next = widget.dispose({
7958
+ helper: helper,
7959
+ state: cleanedState,
7960
+ recommendState: helper.recommendState,
7961
+ parent: container
7962
+ });
7963
+ if (_instanceof(next, algoliasearchHelper.RecommendParameters)) ;
7964
+ else if (next) {
7965
+ cleanedState = next;
7966
+ }
7967
+ }
7968
+ });
7969
+ localWidgets = localWidgets.filter(function(w) {
7970
+ return !flatWidgets.includes(w);
7971
+ });
7972
+ if (cleanedState !== helper.state) {
7973
+ helper.setState(cleanedState);
7974
+ }
7975
+ return container;
7976
+ },
7977
+ init: function init() {
7978
+ initialized = true;
7979
+ localWidgets.forEach(function(widget) {
7980
+ if (widget.getRenderState) {
7981
+ var renderState = widget.getRenderState(instantSearchInstance.renderState[container.getIndexId()] || {}, createInitArgs(instantSearchInstance, container, instantSearchInstance._initialUiState));
7982
+ storeRenderState({
7983
+ renderState: renderState,
7984
+ instantSearchInstance: instantSearchInstance,
7985
+ parent: container
7986
+ });
7987
+ }
7988
+ });
7989
+ localWidgets.forEach(function(widget) {
7990
+ if (widget.init) {
7991
+ widget.init(createInitArgs(instantSearchInstance, container, instantSearchInstance._initialUiState));
7992
+ }
7993
+ });
7994
+ },
7995
+ render: function render() {
7996
+ localWidgets.forEach(function(widget) {
7997
+ if (widget.getRenderState) {
7998
+ var renderState = widget.getRenderState(instantSearchInstance.renderState[container.getIndexId()] || {}, createRenderArgs(instantSearchInstance, container, widget));
7999
+ storeRenderState({
8000
+ renderState: renderState,
8001
+ instantSearchInstance: instantSearchInstance,
8002
+ parent: container
8003
+ });
8004
+ }
8005
+ });
8006
+ localWidgets.forEach(function(widget) {
8007
+ if (widget.render) {
8008
+ widget.render(createRenderArgs(instantSearchInstance, container, widget));
8009
+ }
8010
+ });
8011
+ },
8012
+ dispose: function dispose(disposeOptions) {
8013
+ var _ref;
8014
+ var helper = parentIndex.getHelper();
8015
+ // Chain through children's dispose to return a cleaned state
8016
+ // (e.g. RefinementList.dispose removes its disjunctiveFacet declaration).
8017
+ // This mirrors how the index widget's removeWidgets chains dispose calls.
8018
+ var cleanedState = (_ref = disposeOptions === null || disposeOptions === void 0 ? void 0 : disposeOptions.state) !== null && _ref !== void 0 ? _ref : helper === null || helper === void 0 ? void 0 : helper.state;
8019
+ localWidgets.forEach(function(widget) {
8020
+ if (widget.dispose && helper) {
8021
+ var next = widget.dispose({
8022
+ helper: helper,
8023
+ state: cleanedState,
8024
+ recommendState: helper.recommendState,
8025
+ parent: container
8026
+ });
8027
+ if (_instanceof(next, algoliasearchHelper.RecommendParameters)) ;
8028
+ else if (next) {
8029
+ cleanedState = next;
8030
+ }
8031
+ }
8032
+ });
8033
+ localWidgets = [];
8034
+ initialized = false;
8035
+ return cleanedState;
8036
+ },
8037
+ getWidgetState: function getWidgetState(uiState) {
8038
+ return this.getWidgetUiState(uiState);
8039
+ },
8040
+ getWidgetUiState: function getWidgetUiState(uiState) {
8041
+ var helper = parentIndex.getHelper();
8042
+ var widgetUiStateOptions = {
8043
+ searchParameters: helper.state,
8044
+ helper: helper
8045
+ };
8046
+ return localWidgets.reduce(function(state, widget) {
8047
+ return widget.getWidgetUiState ? widget.getWidgetUiState(state, widgetUiStateOptions) : state;
8048
+ }, uiState);
8049
+ },
8050
+ getWidgetSearchParameters: function getWidgetSearchParameters(searchParameters, param) {
8051
+ var uiState = param.uiState;
8052
+ return localWidgets.reduce(function(params, widget) {
8053
+ return widget.getWidgetSearchParameters ? widget.getWidgetSearchParameters(params, {
8054
+ uiState: uiState
8055
+ }) : params;
8056
+ }, searchParameters);
8057
+ },
8058
+ refreshUiState: function refreshUiState() {
8059
+ // no-op: FeedContainer doesn't own UI state
8060
+ },
8061
+ setIndexUiState: function setIndexUiState() {
8062
+ // no-op: FeedContainer delegates to parent
8063
+ }
8064
+ };
8065
+ return container;
6758
8066
  }
6759
8067
 
6760
- function _to_consumable_array(arr) {
6761
- return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
8068
+ function toFeedSearchResults(state, raw) {
8069
+ return Object.assign(new algoliasearchHelper.SearchResults(state, [
8070
+ raw
8071
+ ]), {
8072
+ feedID: raw.feedID
8073
+ });
6762
8074
  }
6763
-
6764
- var id = 0;
6765
- function addWidgetId(widget) {
6766
- if (widget.dependsOn !== 'recommend') {
8075
+ /**
8076
+ * Rebuild `lastResults.feeds` from `_initialResults.compositionFeedsResults`
8077
+ * because the index-widget hydration only restores `lastResults` (the merged
8078
+ * view), not the per-feed breakdown that the Feeds connector needs.
8079
+ */ function hydrateFeedsFromInitialResultsIfNeeded(instantSearchInstance, parent) {
8080
+ var _instantSearchInstance__initialResults, _parent_getHelper;
8081
+ var initial = (_instantSearchInstance__initialResults = instantSearchInstance._initialResults) === null || _instantSearchInstance__initialResults === void 0 ? void 0 : _instantSearchInstance__initialResults[parent.getIndexId()];
8082
+ var compositionFeedsResults = (initial === null || initial === void 0 ? void 0 : initial.compositionFeedsResults) || [];
8083
+ if (compositionFeedsResults.length === 0) {
6767
8084
  return;
6768
8085
  }
6769
- widget.$$id = id++;
6770
- }
6771
- function resetWidgetId() {
6772
- id = 0;
8086
+ var lastResults = (_parent_getHelper = parent.getHelper()) === null || _parent_getHelper === void 0 ? void 0 : _parent_getHelper.lastResults;
8087
+ if (!lastResults) {
8088
+ return;
8089
+ }
8090
+ if (lastResults.feeds && lastResults.feeds.length > 0) {
8091
+ return;
8092
+ }
8093
+ lastResults.feeds = compositionFeedsResults.map(function(raw) {
8094
+ return toFeedSearchResults(lastResults._state, raw);
8095
+ });
6773
8096
  }
8097
+ var withUsage$s = createDocumentationMessageGenerator({
8098
+ name: 'feeds',
8099
+ connector: true
8100
+ });
8101
+ var connectFeeds = function connectFeeds(renderFn) {
8102
+ var unmountFn = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : noop;
8103
+ checkRendering(renderFn, withUsage$s());
8104
+ return function(widgetParams) {
8105
+ var isolated = widgetParams.isolated, _widgetParams_transformFeeds = widgetParams.transformFeeds, transformFeeds = _widgetParams_transformFeeds === void 0 ? function(feeds) {
8106
+ return feeds;
8107
+ } : _widgetParams_transformFeeds;
8108
+ if (isolated !== false) {
8109
+ throw new Error(withUsage$s('The `isolated` option currently only supports `false`.'));
8110
+ }
8111
+ return {
8112
+ $$type: 'ais.feeds',
8113
+ $$widgetType: 'ais.feeds',
8114
+ init: function init(initOptions) {
8115
+ var instantSearchInstance = initOptions.instantSearchInstance;
8116
+ if (!instantSearchInstance.compositionID) {
8117
+ throw new Error(withUsage$s('The `feeds` widget requires a composition-based InstantSearch instance (compositionID must be set).'));
8118
+ }
8119
+ hydrateFeedsFromInitialResultsIfNeeded(instantSearchInstance, initOptions.parent);
8120
+ renderFn(_object_spread_props(_object_spread({}, this.getWidgetRenderState(initOptions)), {
8121
+ instantSearchInstance: instantSearchInstance
8122
+ }), true);
8123
+ },
8124
+ render: function render(renderOptions) {
8125
+ var instantSearchInstance = renderOptions.instantSearchInstance;
8126
+ renderFn(_object_spread_props(_object_spread({}, this.getWidgetRenderState(renderOptions)), {
8127
+ instantSearchInstance: instantSearchInstance
8128
+ }), false);
8129
+ },
8130
+ dispose: function dispose() {
8131
+ unmountFn();
8132
+ },
8133
+ getWidgetSearchParameters: function getWidgetSearchParameters(state) {
8134
+ return state;
8135
+ },
8136
+ getRenderState: function getRenderState(renderState, renderOptions) {
8137
+ return _object_spread_props(_object_spread({}, renderState), {
8138
+ feeds: this.getWidgetRenderState(renderOptions)
8139
+ });
8140
+ },
8141
+ getWidgetRenderState: function getWidgetRenderState(param) {
8142
+ var results = param.results;
8143
+ if (!results) {
8144
+ return {
8145
+ feedIDs: [],
8146
+ widgetParams: widgetParams
8147
+ };
8148
+ }
8149
+ if (Array.isArray(results.feeds) && results.feeds.length > 0 && !results.feeds.every(function(feed) {
8150
+ return _instanceof(feed, algoliasearchHelper.SearchResults);
8151
+ })) {
8152
+ results.feeds = results.feeds.map(function(feed) {
8153
+ return _instanceof(feed, algoliasearchHelper.SearchResults) ? feed : toFeedSearchResults(results._state, feed);
8154
+ });
8155
+ }
8156
+ var feedIDs = results.feeds ? results.feeds.map(function(f) {
8157
+ return f.feedID;
8158
+ }) : [
8159
+ ''
8160
+ ];
8161
+ feedIDs = transformFeeds(feedIDs);
8162
+ if (!Array.isArray(feedIDs)) {
8163
+ throw new Error(withUsage$s('The `transformFeeds` option expects a function that returns an Array.'));
8164
+ }
8165
+ if (!feedIDs.every(function(feedID) {
8166
+ return typeof feedID === 'string';
8167
+ })) {
8168
+ throw new Error(withUsage$s('The `transformFeeds` option expects a function that returns an array of feed IDs (strings).'));
8169
+ }
8170
+ return {
8171
+ feedIDs: feedIDs,
8172
+ widgetParams: widgetParams
8173
+ };
8174
+ }
8175
+ };
8176
+ };
8177
+ };
6774
8178
 
6775
- function isIndexWidget(widget) {
6776
- return widget.$$type === 'ais.index';
8179
+ function useFeeds(props, additionalWidgetProperties) {
8180
+ return useConnector(connectFeeds, props, additionalWidgetProperties);
6777
8181
  }
6778
8182
 
6779
- var nextMicroTask = Promise.resolve();
6780
- function defer(callback) {
6781
- var progress = null;
6782
- var cancelled = false;
6783
- var fn = function fn() {
6784
- for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
6785
- args[_key] = arguments[_key];
6786
- }
6787
- if (progress !== null) {
6788
- return;
6789
- }
6790
- progress = nextMicroTask.then(function() {
6791
- progress = null;
6792
- if (cancelled) {
6793
- cancelled = false;
8183
+ function Feeds(_0) {
8184
+ var renderFeed = _0.renderFeed, props = _object_without_properties(_0, [
8185
+ "renderFeed"
8186
+ ]);
8187
+ var feedIDs = useFeeds(props, {
8188
+ $$widgetType: 'ais.feeds'
8189
+ }).feedIDs;
8190
+ var parentIndex = useIndexContext();
8191
+ var instantSearchInstance = useInstantSearchContext();
8192
+ var feedContainersRef = React.useRef(new Map());
8193
+ var removalTimerRef = React.useRef(null);
8194
+ var pendingRemovalsRef = React.useRef(new Map());
8195
+ // Create and register new FeedContainers synchronously so SSR and the first
8196
+ // client render can provide the matching feed index context to children.
8197
+ var toAdd = [];
8198
+ feedIDs.forEach(function(feedID) {
8199
+ if (!feedContainersRef.current.has(feedID)) {
8200
+ var pendingContainer = pendingRemovalsRef.current.get(feedID);
8201
+ if (pendingContainer) {
8202
+ pendingRemovalsRef.current.delete(feedID);
8203
+ feedContainersRef.current.set(feedID, pendingContainer);
6794
8204
  return;
6795
8205
  }
6796
- callback.apply(void 0, _to_consumable_array(args));
8206
+ var container = createFeedContainer(feedID, parentIndex, instantSearchInstance);
8207
+ feedContainersRef.current.set(feedID, container);
8208
+ toAdd.push(container);
8209
+ }
8210
+ });
8211
+ if (toAdd.length > 0) {
8212
+ parentIndex.addWidgets(toAdd);
8213
+ }
8214
+ // Remove containers that are no longer in feedIDs (deferred to match useWidget pattern).
8215
+ React.useEffect(function() {
8216
+ var containers = feedContainersRef.current;
8217
+ var activeSet = new Set(feedIDs);
8218
+ var toRemove = [];
8219
+ containers.forEach(function(container, id) {
8220
+ if (!activeSet.has(id)) {
8221
+ toRemove.push([
8222
+ id,
8223
+ container
8224
+ ]);
8225
+ containers.delete(id);
8226
+ }
6797
8227
  });
6798
- };
6799
- fn.wait = function() {
6800
- if (progress === null) {
6801
- throw new Error('The deferred function should be called before calling `wait()`');
8228
+ if (toRemove.length > 0) {
8229
+ toRemove.forEach(function(param) {
8230
+ var _param = _sliced_to_array(param, 2), id = _param[0], container = _param[1];
8231
+ pendingRemovalsRef.current.set(id, container);
8232
+ });
8233
+ if (removalTimerRef.current !== null) {
8234
+ clearTimeout(removalTimerRef.current);
8235
+ }
8236
+ removalTimerRef.current = setTimeout(function() {
8237
+ var widgetsToRemove = Array.from(pendingRemovalsRef.current.values());
8238
+ pendingRemovalsRef.current.clear();
8239
+ removalTimerRef.current = null;
8240
+ if (widgetsToRemove.length > 0) {
8241
+ parentIndex.removeWidgets(widgetsToRemove);
8242
+ }
8243
+ }, 0);
6802
8244
  }
6803
- return progress;
6804
- };
6805
- fn.cancel = function() {
6806
- if (progress === null) {
6807
- return;
8245
+ }, [
8246
+ feedIDs,
8247
+ parentIndex
8248
+ ]);
8249
+ React.useEffect(function() {
8250
+ return function() {
8251
+ if (removalTimerRef.current !== null) {
8252
+ clearTimeout(removalTimerRef.current);
8253
+ removalTimerRef.current = null;
8254
+ }
8255
+ var containers = feedContainersRef.current;
8256
+ var toRemove = Array.from(new Set(_to_consumable_array(containers.values()).concat(_to_consumable_array(pendingRemovalsRef.current.values()))));
8257
+ pendingRemovalsRef.current.clear();
8258
+ containers.clear();
8259
+ if (toRemove.length > 0) {
8260
+ parentIndex.removeWidgets(toRemove);
8261
+ }
8262
+ };
8263
+ // eslint-disable-next-line react-hooks/exhaustive-deps
8264
+ }, []);
8265
+ return /*#__PURE__*/ React.createElement(React.Fragment, null, feedIDs.map(function(feedID) {
8266
+ var container = feedContainersRef.current.get(feedID);
8267
+ if (!container) {
8268
+ return null;
6808
8269
  }
6809
- cancelled = true;
6810
- };
6811
- return fn;
6812
- }
6813
-
6814
- function resolveSearchParameters(current) {
6815
- var parent = current.getParent();
6816
- var states = [
6817
- current.getHelper().state
6818
- ];
6819
- while(parent !== null){
6820
- states = [
6821
- parent.getHelper().state
6822
- ].concat(states);
6823
- parent = parent.getParent();
6824
- }
6825
- return states;
6826
- }
6827
-
6828
- function createInitArgs(instantSearchInstance, parent, uiState) {
6829
- var helper = parent.getHelper();
6830
- return {
6831
- uiState: uiState,
6832
- helper: helper,
6833
- parent: parent,
6834
- instantSearchInstance: instantSearchInstance,
6835
- state: helper.state,
6836
- renderState: instantSearchInstance.renderState,
6837
- templatesConfig: instantSearchInstance.templatesConfig,
6838
- createURL: parent.createURL,
6839
- scopedResults: [],
6840
- searchMetadata: {
6841
- isSearchStalled: instantSearchInstance.status === 'stalled'
6842
- },
6843
- status: instantSearchInstance.status,
6844
- error: instantSearchInstance.error
6845
- };
6846
- }
6847
- function createRenderArgs(instantSearchInstance, parent, widget) {
6848
- var results = parent.getResultsForWidget(widget);
6849
- var helper = parent.getHelper();
6850
- return {
6851
- helper: helper,
6852
- parent: parent,
6853
- instantSearchInstance: instantSearchInstance,
6854
- results: results,
6855
- scopedResults: parent.getScopedResults(),
6856
- state: results && '_state' in results ? results._state : helper.state,
6857
- renderState: instantSearchInstance.renderState,
6858
- templatesConfig: instantSearchInstance.templatesConfig,
6859
- createURL: parent.createURL,
6860
- searchMetadata: {
6861
- isSearchStalled: instantSearchInstance.status === 'stalled'
6862
- },
6863
- status: instantSearchInstance.status,
6864
- error: instantSearchInstance.error
6865
- };
8270
+ return /*#__PURE__*/ React.createElement(IndexContext.Provider, {
8271
+ key: feedID,
8272
+ value: container
8273
+ }, renderFeed({
8274
+ feedID: feedID
8275
+ }));
8276
+ }));
6866
8277
  }
6867
8278
 
6868
8279
  var withUsage$r = createDocumentationMessageGenerator({
@@ -7482,11 +8893,6 @@
7482
8893
  }
7483
8894
  };
7484
8895
  };
7485
- function storeRenderState(param) {
7486
- var renderState = param.renderState, instantSearchInstance = param.instantSearchInstance, parent = param.parent;
7487
- var parentIndexName = parent ? parent.getIndexId() : instantSearchInstance.mainIndex.getIndexId();
7488
- instantSearchInstance.renderState = _object_spread_props(_object_spread({}, instantSearchInstance.renderState), _define_property({}, parentIndexName, _object_spread({}, instantSearchInstance.renderState[parentIndexName], renderState)));
7489
- }
7490
8896
  /**
7491
8897
  * Walk up the parent chain to find the closest isolated index, or fall back to mainHelper
7492
8898
  */ function nearestIsolatedHelper(current, mainHelper) {
@@ -7633,116 +9039,49 @@
7633
9039
  if (typeof superClass !== "function" && superClass !== null) {
7634
9040
  throw new TypeError("Super expression must either be null or a function");
7635
9041
  }
7636
-
7637
- subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } });
7638
-
7639
- if (superClass) _set_prototype_of(subClass, superClass);
7640
- }
7641
-
7642
- var eventsExports = requireEvents();
7643
- var EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventsExports);
7644
-
7645
- /**
7646
- * Create UUID according to
7647
- * https://www.ietf.org/rfc/rfc4122.txt.
7648
- *
7649
- * @returns Generated UUID.
7650
- */ function createUUID() {
7651
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
7652
- /* eslint-disable no-bitwise */ var r = Math.random() * 16 | 0;
7653
- var v = c === 'x' ? r : r & 0x3 | 0x8;
7654
- /* eslint-enable */ return v.toString(16);
7655
- });
7656
- }
7657
-
7658
- var ANONYMOUS_TOKEN_COOKIE_KEY = '_ALGOLIA';
7659
- function getCookie(name) {
7660
- if ((typeof document === "undefined" ? "undefined" : _type_of(document)) !== 'object' || typeof document.cookie !== 'string') {
7661
- return undefined;
7662
- }
7663
- var prefix = "".concat(name, "=");
7664
- var cookies = document.cookie.split(';');
7665
- for(var i = 0; i < cookies.length; i++){
7666
- var cookie = cookies[i];
7667
- while(cookie.charAt(0) === ' '){
7668
- cookie = cookie.substring(1);
7669
- }
7670
- if (cookie.indexOf(prefix) === 0) {
7671
- return cookie.substring(prefix.length, cookie.length);
7672
- }
7673
- }
7674
- return undefined;
7675
- }
7676
- function getInsightsAnonymousUserTokenInternal() {
7677
- return getCookie(ANONYMOUS_TOKEN_COOKIE_KEY);
7678
- }
7679
-
7680
- // eslint-disable-next-line no-restricted-globals
7681
- /**
7682
- * Runs code on browser environments safely.
7683
- */ function safelyRunOnBrowser(callback) {
7684
- var fallback = (arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {
7685
- fallback: function fallback() {
7686
- return undefined;
7687
- }
7688
- }).fallback;
7689
- // eslint-disable-next-line no-restricted-globals
7690
- if (typeof window === 'undefined') {
7691
- return fallback();
7692
- }
7693
- // eslint-disable-next-line no-restricted-globals
7694
- return callback({
7695
- window: window
7696
- });
7697
- }
7698
-
7699
- // typed as any, since it accepts the _real_ js clients, not the interface we otherwise expect
7700
- function getAppIdAndApiKey(searchClient) {
7701
- if (searchClient.appId && searchClient.apiKey) {
7702
- // searchClient v5
7703
- return [
7704
- searchClient.appId,
7705
- searchClient.apiKey
7706
- ];
7707
- } else if (searchClient.transporter) {
7708
- // searchClient v4 or v5
7709
- var transporter = searchClient.transporter;
7710
- var headers = transporter.headers || transporter.baseHeaders;
7711
- var queryParameters = transporter.queryParameters || transporter.baseQueryParameters;
7712
- var APP_ID = 'x-algolia-application-id';
7713
- var API_KEY = 'x-algolia-api-key';
7714
- var appId = headers[APP_ID] || queryParameters[APP_ID];
7715
- var apiKey = headers[API_KEY] || queryParameters[API_KEY];
7716
- return [
7717
- appId,
7718
- apiKey
7719
- ];
7720
- } else {
7721
- // searchClient v3
7722
- return [
7723
- searchClient.applicationID,
7724
- searchClient.apiKey
7725
- ];
7726
- }
9042
+
9043
+ subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } });
9044
+
9045
+ if (superClass) _set_prototype_of(subClass, superClass);
7727
9046
  }
7728
9047
 
7729
- // We aren't using the native `Array.prototype.find` because the refactor away from Lodash is not
7730
- // published as a major version.
7731
- // Relying on the `find` polyfill on user-land, which before was only required for niche use-cases,
7732
- // was decided as too risky.
7733
- // @MAJOR Replace with the native `Array.prototype.find` method
7734
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
7735
- function find(items, predicate) {
7736
- var value;
7737
- for(var i = 0; i < items.length; i++){
7738
- value = items[i];
7739
- // inlined for performance: if (Call(predicate, thisArg, [value, i, list])) {
7740
- if (predicate(value, i, items)) {
7741
- return value;
9048
+ var eventsExports = requireEvents();
9049
+ var EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventsExports);
9050
+
9051
+ /**
9052
+ * Create UUID according to
9053
+ * https://www.ietf.org/rfc/rfc4122.txt.
9054
+ *
9055
+ * @returns Generated UUID.
9056
+ */ function createUUID() {
9057
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
9058
+ /* eslint-disable no-bitwise */ var r = Math.random() * 16 | 0;
9059
+ var v = c === 'x' ? r : r & 0x3 | 0x8;
9060
+ /* eslint-enable */ return v.toString(16);
9061
+ });
9062
+ }
9063
+
9064
+ var ANONYMOUS_TOKEN_COOKIE_KEY = '_ALGOLIA';
9065
+ function getCookie(name) {
9066
+ if ((typeof document === "undefined" ? "undefined" : _type_of(document)) !== 'object' || typeof document.cookie !== 'string') {
9067
+ return undefined;
9068
+ }
9069
+ var prefix = "".concat(name, "=");
9070
+ var cookies = document.cookie.split(';');
9071
+ for(var i = 0; i < cookies.length; i++){
9072
+ var cookie = cookies[i];
9073
+ while(cookie.charAt(0) === ' '){
9074
+ cookie = cookie.substring(1);
9075
+ }
9076
+ if (cookie.indexOf(prefix) === 0) {
9077
+ return cookie.substring(prefix.length, cookie.length);
7742
9078
  }
7743
9079
  }
7744
9080
  return undefined;
7745
9081
  }
9082
+ function getInsightsAnonymousUserTokenInternal() {
9083
+ return getCookie(ANONYMOUS_TOKEN_COOKIE_KEY);
9084
+ }
7746
9085
 
7747
9086
  var ALGOLIA_INSIGHTS_VERSION = '2.17.2';
7748
9087
  var ALGOLIA_INSIGHTS_SRC = "https://cdn.jsdelivr.net/npm/search-insights@".concat(ALGOLIA_INSIGHTS_VERSION, "/dist/search-insights.min.js");
@@ -8058,11 +9397,6 @@
8058
9397
  return typeof userToken === 'number' ? userToken.toString() : userToken;
8059
9398
  }
8060
9399
 
8061
- function getAlgoliaAgent(client) {
8062
- var clientTyped = client;
8063
- return clientTyped.transporter && clientTyped.transporter.userAgent ? clientTyped.transporter.userAgent.value : clientTyped._ua;
8064
- }
8065
-
8066
9400
  function extractWidgetPayload(widgets, instantSearchInstance, payload) {
8067
9401
  var initOptions = createInitArgs(instantSearchInstance, instantSearchInstance.mainIndex, instantSearchInstance._initialUiState);
8068
9402
  widgets.forEach(function(widget) {
@@ -8083,7 +9417,7 @@
8083
9417
  widgetType: widget.$$widgetType,
8084
9418
  params: params
8085
9419
  });
8086
- if (widget.$$type === 'ais.index') {
9420
+ if (isIndexWidget(widget)) {
8087
9421
  extractWidgetPayload(widget.getWidgets(), instantSearchInstance, payload);
8088
9422
  }
8089
9423
  });
@@ -9298,55 +10632,16 @@
9298
10632
  routeToState: function routeToState() {
9299
10633
  var routeState = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
9300
10634
  return Object.keys(routeState).reduce(function(state, indexId) {
9301
- return _object_spread_props(_object_spread({}, state), _define_property({}, indexId, getIndexStateWithoutConfigure(routeState[indexId])));
10635
+ var indexState = routeState[indexId];
10636
+ if ((typeof indexState === "undefined" ? "undefined" : _type_of(indexState)) !== 'object' || indexState === null) {
10637
+ return state;
10638
+ }
10639
+ return _object_spread_props(_object_spread({}, state), _define_property({}, indexId, getIndexStateWithoutConfigure(indexState)));
9302
10640
  }, {});
9303
10641
  }
9304
10642
  };
9305
10643
  }
9306
10644
 
9307
- function isPrimitive(obj) {
9308
- return obj !== Object(obj);
9309
- }
9310
- function isEqual(first, second) {
9311
- if (first === second) {
9312
- return true;
9313
- }
9314
- if (isPrimitive(first) || isPrimitive(second) || typeof first === 'function' || typeof second === 'function') {
9315
- return first === second;
9316
- }
9317
- if (Object.keys(first).length !== Object.keys(second).length) {
9318
- return false;
9319
- }
9320
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
9321
- try {
9322
- // @TODO avoid for..of because of the large polyfill
9323
- // eslint-disable-next-line instantsearch/no-for-of
9324
- for(var _iterator = Object.keys(first)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
9325
- var key = _step.value;
9326
- if (!(key in second)) {
9327
- return false;
9328
- }
9329
- if (!isEqual(first[key], second[key])) {
9330
- return false;
9331
- }
9332
- }
9333
- } catch (err) {
9334
- _didIteratorError = true;
9335
- _iteratorError = err;
9336
- } finally{
9337
- try {
9338
- if (!_iteratorNormalCompletion && _iterator.return != null) {
9339
- _iterator.return();
9340
- }
9341
- } finally{
9342
- if (_didIteratorError) {
9343
- throw _iteratorError;
9344
- }
9345
- }
9346
- }
9347
- return true;
9348
- }
9349
-
9350
10645
  var createRouterMiddleware = function createRouterMiddleware() {
9351
10646
  var props = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
9352
10647
  var _props_router = props.router, router = _props_router === void 0 ? historyRouter() : _props_router, _props_stateMapping = props.// this is needed because simpleStateMapping is StateMapping<TUiState, TUiState>.
@@ -9370,176 +10665,53 @@
9370
10665
  }
9371
10666
  // casting to UiState here to keep createURL unaware of custom UiState
9372
10667
  // (as long as it's an object, it's ok)
9373
- instantSearchInstance._createURL = topLevelCreateURL;
9374
- var lastRouteState = undefined;
9375
- var initialUiState = instantSearchInstance._initialUiState;
9376
- return {
9377
- $$type: "ais.router({router:".concat(router.$$type || '__unknown__', ", stateMapping:").concat(stateMapping.$$type || '__unknown__', "})"),
9378
- $$internal: $$internal,
9379
- onStateChange: function onStateChange(param) {
9380
- var uiState = param.uiState;
9381
- var routeState = stateMapping.stateToRoute(uiState);
9382
- if (lastRouteState === undefined || !isEqual(lastRouteState, routeState)) {
9383
- router.write(routeState);
9384
- lastRouteState = routeState;
9385
- }
9386
- },
9387
- subscribe: function subscribe() {
9388
- instantSearchInstance._initialUiState = _object_spread({}, initialUiState, stateMapping.routeToState(router.read()));
9389
- router.onUpdate(function(route) {
9390
- if (instantSearchInstance.mainIndex.getWidgets().length > 0) {
9391
- instantSearchInstance.setUiState(stateMapping.routeToState(route));
9392
- }
9393
- });
9394
- },
9395
- started: function started() {
9396
- var _router_start;
9397
- (_router_start = router.start) === null || _router_start === void 0 ? void 0 : _router_start.call(router);
9398
- },
9399
- unsubscribe: function unsubscribe() {
9400
- router.dispose();
9401
- }
9402
- };
9403
- };
9404
- };
9405
-
9406
- function formatNumber(value, numberLocale) {
9407
- return value.toLocaleString(numberLocale);
9408
- }
9409
-
9410
- var NAMESPACE = 'ais';
9411
- var component = function component(componentName) {
9412
- return function() {
9413
- var _ref = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {}, descendantName = _ref.descendantName, modifierName = _ref.modifierName;
9414
- var descendent = descendantName ? "-".concat(descendantName) : '';
9415
- var modifier = modifierName ? "--".concat(modifierName) : '';
9416
- return "".concat(NAMESPACE, "-").concat(componentName).concat(descendent).concat(modifier);
9417
- };
9418
- };
9419
-
9420
- function getPropertyByPath(object, path) {
9421
- var parts = Array.isArray(path) ? path : path.split('.');
9422
- return parts.reduce(function(current, key) {
9423
- return current && current[key];
9424
- }, object);
9425
- }
9426
-
9427
- function _extends() {
9428
- _extends = Object.assign || function assign(target) {
9429
- for (var i = 1; i < arguments.length; i++) {
9430
- var source = arguments[i];
9431
- for (var key in source) if (Object.prototype.hasOwnProperty.call(source, key)) target[key] = source[key];
9432
- }
9433
-
9434
- return target;
9435
- };
9436
-
9437
- return _extends.apply(this, arguments);
9438
- }
9439
-
9440
- function _object_destructuring_empty(o) {
9441
- if (o === null || o === void 0) throw new TypeError("Cannot destructure " + o);
9442
-
9443
- return o;
9444
- }
9445
-
9446
- /**
9447
- * This implementation is taken from Lodash implementation.
9448
- * See: https://github.com/lodash/lodash/blob/4.17.11-npm/escape.js
9449
- */ // Used to map characters to HTML entities.
9450
- var htmlEntities = {
9451
- '&': '&amp;',
9452
- '<': '&lt;',
9453
- '>': '&gt;',
9454
- '"': '&quot;',
9455
- "'": '&#39;'
9456
- };
9457
- // Used to match HTML entities and HTML characters.
9458
- var regexUnescapedHtml = /[&<>"']/g;
9459
- var regexHasUnescapedHtml = RegExp(regexUnescapedHtml.source);
9460
- /**
9461
- * Converts the characters "&", "<", ">", '"', and "'" in `string` to their
9462
- * corresponding HTML entities.
9463
- */ function escape$1(value) {
9464
- return value && regexHasUnescapedHtml.test(value) ? value.replace(regexUnescapedHtml, function(character) {
9465
- return htmlEntities[character];
9466
- }) : value;
9467
- }
9468
- /**
9469
- * This implementation is taken from Lodash implementation.
9470
- * See: https://github.com/lodash/lodash/blob/4.17.11-npm/unescape.js
9471
- */ // Used to map HTML entities to characters.
9472
- var htmlCharacters = {
9473
- '&amp;': '&',
9474
- '&lt;': '<',
9475
- '&gt;': '>',
9476
- '&quot;': '"',
9477
- '&#39;': "'"
9478
- };
9479
- // Used to match HTML entities and HTML characters.
9480
- var regexEscapedHtml = /&(amp|quot|lt|gt|#39);/g;
9481
- var regexHasEscapedHtml = RegExp(regexEscapedHtml.source);
9482
- /**
9483
- * Converts the HTML entities "&", "<", ">", '"', and "'" in `string` to their
9484
- * characters.
9485
- */ function unescape$1(value) {
9486
- return value && regexHasEscapedHtml.test(value) ? value.replace(regexEscapedHtml, function(character) {
9487
- return htmlCharacters[character];
9488
- }) : value;
9489
- }
9490
-
9491
- var TAG_PLACEHOLDER = {
9492
- highlightPreTag: '__ais-highlight__',
9493
- highlightPostTag: '__/ais-highlight__'
9494
- };
9495
- var TAG_REPLACEMENT = {
9496
- highlightPreTag: '<mark>',
9497
- highlightPostTag: '</mark>'
9498
- };
9499
- // @MAJOR: in the future, this should only escape, not replace
9500
- function replaceTagsAndEscape(value) {
9501
- return escape$1(value).replace(new RegExp(TAG_PLACEHOLDER.highlightPreTag, 'g'), TAG_REPLACEMENT.highlightPreTag).replace(new RegExp(TAG_PLACEHOLDER.highlightPostTag, 'g'), TAG_REPLACEMENT.highlightPostTag);
9502
- }
9503
- function recursiveEscape(input) {
9504
- if (isPlainObject(input) && typeof input.value !== 'string') {
9505
- return Object.keys(input).reduce(function(acc, key) {
9506
- return _object_spread_props(_object_spread({}, acc), _define_property({}, key, recursiveEscape(input[key])));
9507
- }, {});
9508
- }
9509
- if (Array.isArray(input)) {
9510
- return input.map(recursiveEscape);
9511
- }
9512
- return _object_spread_props(_object_spread({}, input), {
9513
- value: replaceTagsAndEscape(input.value)
9514
- });
9515
- }
9516
- function escapeHits(hits) {
9517
- if (hits.__escaped === undefined) {
9518
- // We don't override the value on hit because it will mutate the raw results
9519
- // instead we make a shallow copy and we assign the escaped values on it.
9520
- hits = hits.map(function(_0) {
9521
- _object_destructuring_empty(_0);
9522
- var hit = _extends({}, _0);
9523
- if (hit._highlightResult) {
9524
- hit._highlightResult = recursiveEscape(hit._highlightResult);
9525
- }
9526
- if (hit._snippetResult) {
9527
- hit._snippetResult = recursiveEscape(hit._snippetResult);
10668
+ instantSearchInstance._createURL = topLevelCreateURL;
10669
+ var lastRouteState = undefined;
10670
+ var initialUiState = instantSearchInstance._initialUiState;
10671
+ return {
10672
+ $$type: "ais.router({router:".concat(router.$$type || '__unknown__', ", stateMapping:").concat(stateMapping.$$type || '__unknown__', "})"),
10673
+ $$internal: $$internal,
10674
+ onStateChange: function onStateChange(param) {
10675
+ var uiState = param.uiState;
10676
+ var routeState = stateMapping.stateToRoute(uiState);
10677
+ if (lastRouteState === undefined || !isEqual(lastRouteState, routeState)) {
10678
+ router.write(routeState);
10679
+ lastRouteState = routeState;
10680
+ }
10681
+ },
10682
+ subscribe: function subscribe() {
10683
+ instantSearchInstance._initialUiState = _object_spread({}, initialUiState, stateMapping.routeToState(router.read()));
10684
+ router.onUpdate(function(route) {
10685
+ if (instantSearchInstance.mainIndex.getWidgets().length > 0) {
10686
+ instantSearchInstance.setUiState(stateMapping.routeToState(route));
10687
+ }
10688
+ });
10689
+ },
10690
+ started: function started() {
10691
+ var _router_start;
10692
+ (_router_start = router.start) === null || _router_start === void 0 ? void 0 : _router_start.call(router);
10693
+ },
10694
+ unsubscribe: function unsubscribe() {
10695
+ router.dispose();
9528
10696
  }
9529
- return hit;
9530
- });
9531
- hits.__escaped = true;
9532
- }
9533
- return hits;
9534
- }
9535
- function escapeFacets(facetHits) {
9536
- return facetHits.map(function(h) {
9537
- return _object_spread_props(_object_spread({}, h), {
9538
- highlighted: replaceTagsAndEscape(h.highlighted)
9539
- });
9540
- });
10697
+ };
10698
+ };
10699
+ };
10700
+
10701
+ function formatNumber(value, numberLocale) {
10702
+ return value.toLocaleString(numberLocale);
9541
10703
  }
9542
10704
 
10705
+ var NAMESPACE = 'ais';
10706
+ var component = function component(componentName) {
10707
+ return function() {
10708
+ var _ref = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {}, descendantName = _ref.descendantName, modifierName = _ref.modifierName;
10709
+ var descendent = descendantName ? "-".concat(descendantName) : '';
10710
+ var modifier = modifierName ? "--".concat(modifierName) : '';
10711
+ return "".concat(NAMESPACE, "-").concat(componentName).concat(descendent).concat(modifier);
10712
+ };
10713
+ };
10714
+
9543
10715
  var suit$3 = component('Highlight');
9544
10716
  /**
9545
10717
  * @deprecated use html tagged templates and the Highlight component instead
@@ -9554,69 +10726,6 @@
9554
10726
  return attributeValue.replace(new RegExp(TAG_REPLACEMENT.highlightPreTag, 'g'), "<".concat(highlightedTagName, ' class="').concat(className, '">')).replace(new RegExp(TAG_REPLACEMENT.highlightPostTag, 'g'), "</".concat(highlightedTagName, ">"));
9555
10727
  }
9556
10728
 
9557
- function concatHighlightedParts(parts) {
9558
- var highlightPreTag = TAG_REPLACEMENT.highlightPreTag, highlightPostTag = TAG_REPLACEMENT.highlightPostTag;
9559
- return parts.map(function(part) {
9560
- return part.isHighlighted ? highlightPreTag + part.value + highlightPostTag : part.value;
9561
- }).join('');
9562
- }
9563
-
9564
- var hasAlphanumeric = new RegExp(/\w/i);
9565
- function getHighlightFromSiblings(parts, i) {
9566
- var _parts_, _parts_1;
9567
- var current = parts[i];
9568
- var isNextHighlighted = ((_parts_ = parts[i + 1]) === null || _parts_ === void 0 ? void 0 : _parts_.isHighlighted) || true;
9569
- var isPreviousHighlighted = ((_parts_1 = parts[i - 1]) === null || _parts_1 === void 0 ? void 0 : _parts_1.isHighlighted) || true;
9570
- if (!hasAlphanumeric.test(unescape$1(current.value)) && isPreviousHighlighted === isNextHighlighted) {
9571
- return isPreviousHighlighted;
9572
- }
9573
- return current.isHighlighted;
9574
- }
9575
-
9576
- function reverseHighlightedParts(parts) {
9577
- if (!parts.some(function(part) {
9578
- return part.isHighlighted;
9579
- })) {
9580
- return parts.map(function(part) {
9581
- return _object_spread_props(_object_spread({}, part), {
9582
- isHighlighted: false
9583
- });
9584
- });
9585
- }
9586
- return parts.map(function(part, i) {
9587
- return _object_spread_props(_object_spread({}, part), {
9588
- isHighlighted: !getHighlightFromSiblings(parts, i)
9589
- });
9590
- });
9591
- }
9592
-
9593
- function getHighlightedParts(highlightedValue) {
9594
- // @MAJOR: this should use TAG_PLACEHOLDER
9595
- var highlightPostTag = TAG_REPLACEMENT.highlightPostTag, highlightPreTag = TAG_REPLACEMENT.highlightPreTag;
9596
- var splitByPreTag = highlightedValue.split(highlightPreTag);
9597
- var firstValue = splitByPreTag.shift();
9598
- var elements = !firstValue ? [] : [
9599
- {
9600
- value: firstValue,
9601
- isHighlighted: false
9602
- }
9603
- ];
9604
- splitByPreTag.forEach(function(split) {
9605
- var splitByPostTag = split.split(highlightPostTag);
9606
- elements.push({
9607
- value: splitByPostTag[0],
9608
- isHighlighted: true
9609
- });
9610
- if (splitByPostTag[1] !== '') {
9611
- elements.push({
9612
- value: splitByPostTag[1],
9613
- isHighlighted: false
9614
- });
9615
- }
9616
- });
9617
- return elements;
9618
- }
9619
-
9620
10729
  var suit$2 = component('ReverseHighlight');
9621
10730
  /**
9622
10731
  * @deprecated use html tagged templates and the ReverseHighlight component instead
@@ -9661,10 +10770,6 @@
9661
10770
  return reverseHighlightedValue.replace(new RegExp(TAG_REPLACEMENT.highlightPreTag, 'g'), "<".concat(highlightedTagName, ' class="').concat(className, '">')).replace(new RegExp(TAG_REPLACEMENT.highlightPostTag, 'g'), "</".concat(highlightedTagName, ">"));
9662
10771
  }
9663
10772
 
9664
- function serializePayload(payload) {
9665
- return btoa(encodeURIComponent(JSON.stringify(payload)));
9666
- }
9667
-
9668
10773
  /** @deprecated use bindEvent instead */ function writeDataAttributes(param) {
9669
10774
  var method = param.method, payload = param.payload;
9670
10775
  if ((typeof payload === "undefined" ? "undefined" : _type_of(payload)) !== 'object') {
@@ -9713,175 +10818,42 @@
9713
10818
  throw new Error('\n The reverseHighlight helper expects a JSON object of the format:\n { "attribute": "name", "highlightedTagName": "mark" }');
9714
10819
  }
9715
10820
  },
9716
- snippet: function snippet1(options, render) {
9717
- try {
9718
- var snippetOptions = JSON.parse(options);
9719
- return render(snippet(_object_spread_props(_object_spread({}, snippetOptions), {
9720
- hit: this
9721
- })));
9722
- } catch (error) {
9723
- throw new Error('\nThe snippet helper expects a JSON object of the format:\n{ "attribute": "name", "highlightedTagName": "mark" }');
9724
- }
9725
- },
9726
- reverseSnippet: function reverseSnippet1(options, render) {
9727
- try {
9728
- var reverseSnippetOptions = JSON.parse(options);
9729
- return render(reverseSnippet(_object_spread_props(_object_spread({}, reverseSnippetOptions), {
9730
- hit: this
9731
- })));
9732
- } catch (error) {
9733
- throw new Error('\n The reverseSnippet helper expects a JSON object of the format:\n { "attribute": "name", "highlightedTagName": "mark" }');
9734
- }
9735
- },
9736
- insights: function insights1(options, render) {
9737
- try {
9738
- var _JSON_parse = JSON.parse(options), method = _JSON_parse.method, payload = _JSON_parse.payload;
9739
- return render(insights(method, _object_spread({
9740
- objectIDs: [
9741
- this.objectID
9742
- ]
9743
- }, payload)));
9744
- } catch (error) {
9745
- throw new Error('\nThe insights helper expects a JSON object of the format:\n{ "method": "method-name", "payload": { "eventName": "name of the event" } }');
9746
- }
9747
- }
9748
- };
9749
- }
9750
-
9751
- var version = '4.95.0';
9752
-
9753
- function hydrateSearchClient(client, results) {
9754
- if (!results) {
9755
- return;
9756
- }
9757
- // Disable cache hydration on:
9758
- // - Algoliasearch API Client < v4 with cache disabled
9759
- // - Third party clients (detected by the `addAlgoliaAgent` function missing)
9760
- if ((!('transporter' in client) || client._cacheHydrated) && (!client._useCache || typeof client.addAlgoliaAgent !== 'function')) {
9761
- return;
9762
- }
9763
- var cachedRequest = [
9764
- Object.keys(results).reduce(function(acc, key) {
9765
- var _results_key = results[key], state = _results_key.state, requestParams = _results_key.requestParams, serverResults = _results_key.results;
9766
- var mappedResults = serverResults && state ? serverResults.map(function(result, idx) {
9767
- return _object_spread({
9768
- indexName: state.index || result.index
9769
- }, (requestParams === null || requestParams === void 0 ? void 0 : requestParams[idx]) || result.params ? {
9770
- params: serializeQueryParameters((requestParams === null || requestParams === void 0 ? void 0 : requestParams[idx]) || deserializeQueryParameters(result.params))
9771
- } : {});
9772
- }) : [];
9773
- return acc.concat(mappedResults);
9774
- }, [])
9775
- ];
9776
- var cachedResults = Object.keys(results).reduce(function(acc, key) {
9777
- var res = results[key].results;
9778
- if (!res) {
9779
- return acc;
9780
- }
9781
- return acc.concat(res);
9782
- }, []);
9783
- // Algoliasearch API Client >= v4
9784
- // To hydrate the client we need to populate the cache with the data from
9785
- // the server (done in `hydrateSearchClientWithMultiIndexRequest` or
9786
- // `hydrateSearchClientWithSingleIndexRequest`). But since there is no way
9787
- // for us to compute the key the same way as `algoliasearch-client` we need
9788
- // to populate it on a custom key and override the `search` method to
9789
- // search on it first.
9790
- if ('transporter' in client && !client._cacheHydrated) {
9791
- client._cacheHydrated = true;
9792
- var baseMethod = client.search.bind(client);
9793
- client.search = function(requests) {
9794
- for(var _len = arguments.length, methodArgs = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++){
9795
- methodArgs[_key - 1] = arguments[_key];
9796
- }
9797
- var requestsWithSerializedParams = Array.isArray(requests) ? requests.map(function(request) {
9798
- return _object_spread_props(_object_spread({}, request), {
9799
- params: serializeQueryParameters(request.params)
9800
- });
9801
- }) : serializeQueryParameters(requests.requestBody.params);
9802
- return client.transporter.responsesCache.get({
9803
- method: 'search',
9804
- args: [
9805
- requestsWithSerializedParams
9806
- ].concat(_to_consumable_array(methodArgs))
9807
- }, function() {
9808
- return baseMethod.apply(void 0, [
9809
- requests
9810
- ].concat(_to_consumable_array(methodArgs)));
9811
- });
9812
- };
9813
- client.transporter.responsesCache.set({
9814
- method: 'search',
9815
- args: cachedRequest
9816
- }, {
9817
- results: cachedResults
9818
- });
9819
- }
9820
- // Algoliasearch API Client < v4
9821
- // Prior to client v4 we didn't have a proper API to hydrate the client
9822
- // cache from the outside. The following code populates the cache with
9823
- // a single-index result. You can find more information about the
9824
- // computation of the key inside the client (see link below).
9825
- // https://github.com/algolia/algoliasearch-client-javascript/blob/c27e89ff92b2a854ae6f40dc524bffe0f0cbc169/src/AlgoliaSearchCore.js#L232-L240
9826
- if (!('transporter' in client)) {
9827
- var cacheKey = "/1/indexes/*/queries_body_".concat(JSON.stringify({
9828
- requests: cachedRequest
9829
- }));
9830
- client.cache = _object_spread_props(_object_spread({}, client.cache), _define_property({}, cacheKey, JSON.stringify({
9831
- results: Object.keys(results).map(function(key) {
9832
- return results[key].results;
9833
- })
9834
- })));
9835
- }
9836
- }
9837
- function deserializeQueryParameters(parameters) {
9838
- return parameters.split('&').reduce(function(acc, parameter) {
9839
- var _parameter_split = _sliced_to_array(parameter.split('='), 2), key = _parameter_split[0], value = _parameter_split[1];
9840
- acc[key] = value ? decodeURIComponent(value) : '';
9841
- return acc;
9842
- }, {});
9843
- }
9844
- // This function is copied from the algoliasearch v4 API Client. If modified,
9845
- // consider updating it also in `serializeQueryParameters` from `@algolia/transporter`.
9846
- function serializeQueryParameters(parameters) {
9847
- var isObjectOrArray = function isObjectOrArray(value) {
9848
- return Object.prototype.toString.call(value) === '[object Object]' || Object.prototype.toString.call(value) === '[object Array]';
9849
- };
9850
- var encode = function encode(format) {
9851
- for(var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++){
9852
- args[_key - 1] = arguments[_key];
10821
+ snippet: function snippet1(options, render) {
10822
+ try {
10823
+ var snippetOptions = JSON.parse(options);
10824
+ return render(snippet(_object_spread_props(_object_spread({}, snippetOptions), {
10825
+ hit: this
10826
+ })));
10827
+ } catch (error) {
10828
+ throw new Error('\nThe snippet helper expects a JSON object of the format:\n{ "attribute": "name", "highlightedTagName": "mark" }');
10829
+ }
10830
+ },
10831
+ reverseSnippet: function reverseSnippet1(options, render) {
10832
+ try {
10833
+ var reverseSnippetOptions = JSON.parse(options);
10834
+ return render(reverseSnippet(_object_spread_props(_object_spread({}, reverseSnippetOptions), {
10835
+ hit: this
10836
+ })));
10837
+ } catch (error) {
10838
+ throw new Error('\n The reverseSnippet helper expects a JSON object of the format:\n { "attribute": "name", "highlightedTagName": "mark" }');
10839
+ }
10840
+ },
10841
+ insights: function insights1(options, render) {
10842
+ try {
10843
+ var _JSON_parse = JSON.parse(options), method = _JSON_parse.method, payload = _JSON_parse.payload;
10844
+ return render(insights(method, _object_spread({
10845
+ objectIDs: [
10846
+ this.objectID
10847
+ ]
10848
+ }, payload)));
10849
+ } catch (error) {
10850
+ throw new Error('\nThe insights helper expects a JSON object of the format:\n{ "method": "method-name", "payload": { "eventName": "name of the event" } }');
10851
+ }
9853
10852
  }
9854
- var i = 0;
9855
- return format.replace(/%s/g, function() {
9856
- return encodeURIComponent(args[i++]);
9857
- });
9858
10853
  };
9859
- return Object.keys(parameters).map(function(key) {
9860
- return encode('%s=%s', key, isObjectOrArray(parameters[key]) ? JSON.stringify(parameters[key]) : parameters[key]);
9861
- }).join('&');
9862
- }
9863
-
9864
- function hydrateRecommendCache(helper, initialResults) {
9865
- var recommendCache = Object.keys(initialResults).reduce(function(acc, indexName) {
9866
- var initialResult = initialResults[indexName];
9867
- if (initialResult.recommendResults) {
9868
- // @MAJOR: Use `Object.assign` instead of spread operator
9869
- return _object_spread({}, acc, initialResult.recommendResults.results);
9870
- }
9871
- return acc;
9872
- }, {});
9873
- helper._recommendCache = recommendCache;
9874
10854
  }
9875
10855
 
9876
- function setIndexHelperState(finalUiState, indexWidget) {
9877
- var nextIndexUiState = finalUiState[indexWidget.getIndexId()] || {};
9878
- indexWidget.getHelper().setState(indexWidget.getWidgetSearchParameters(indexWidget.getHelper().state, {
9879
- uiState: nextIndexUiState
9880
- }));
9881
- indexWidget.getWidgets().filter(isIndexWidget).forEach(function(widget) {
9882
- return setIndexHelperState(finalUiState, widget);
9883
- });
9884
- }
10856
+ var version = '4.96.1';
9885
10857
 
9886
10858
  var withUsage$q = createDocumentationMessageGenerator({
9887
10859
  name: 'instantsearch'
@@ -10918,180 +11890,6 @@
10918
11890
  }, children);
10919
11891
  }
10920
11892
 
10921
- function chunk(arr) {
10922
- var chunkSize = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 20;
10923
- var chunks = [];
10924
- for(var i = 0; i < Math.ceil(arr.length / chunkSize); i++){
10925
- chunks.push(arr.slice(i * chunkSize, (i + 1) * chunkSize));
10926
- }
10927
- return chunks;
10928
- }
10929
- function _buildEventPayloadsForHits(param) {
10930
- var helper = param.helper, widgetType = param.widgetType;
10931
- param.methodName;
10932
- var args = param.args, instantSearchInstance = param.instantSearchInstance;
10933
- // when there's only one argument, that means it's custom
10934
- if (args.length === 1 && _type_of(args[0]) === 'object') {
10935
- return [
10936
- args[0]
10937
- ];
10938
- }
10939
- var _args__split = _sliced_to_array(args[0].split(':'), 2), eventType = _args__split[0], eventModifier = _args__split[1];
10940
- var hits = args[1];
10941
- var eventName = args[2];
10942
- var additionalData = args[3] || {};
10943
- if (!hits) {
10944
- {
10945
- return [];
10946
- }
10947
- }
10948
- if ((eventType === 'click' || eventType === 'conversion') && !eventName) {
10949
- {
10950
- return [];
10951
- }
10952
- }
10953
- var hitsArray = Array.isArray(hits) ? hits : [
10954
- hits
10955
- ];
10956
- if (hitsArray.length === 0) {
10957
- return [];
10958
- }
10959
- var queryID = hitsArray[0].__queryID;
10960
- var hitsChunks = chunk(hitsArray);
10961
- var objectIDsByChunk = hitsChunks.map(function(batch) {
10962
- return batch.map(function(hit) {
10963
- return hit.objectID;
10964
- });
10965
- });
10966
- var positionsByChunk = hitsChunks.map(function(batch) {
10967
- return batch.map(function(hit) {
10968
- return hit.__position;
10969
- });
10970
- });
10971
- if (eventType === 'view') {
10972
- if (instantSearchInstance.status !== 'idle') {
10973
- return [];
10974
- }
10975
- return hitsChunks.map(function(batch, i) {
10976
- var _helper_lastResults;
10977
- return {
10978
- insightsMethod: 'viewedObjectIDs',
10979
- widgetType: widgetType,
10980
- eventType: eventType,
10981
- payload: _object_spread({
10982
- eventName: eventName || 'Hits Viewed',
10983
- index: ((_helper_lastResults = helper.lastResults) === null || _helper_lastResults === void 0 ? void 0 : _helper_lastResults.index) || helper.state.index,
10984
- objectIDs: objectIDsByChunk[i]
10985
- }, additionalData),
10986
- hits: batch,
10987
- eventModifier: eventModifier
10988
- };
10989
- });
10990
- } else if (eventType === 'click') {
10991
- return hitsChunks.map(function(batch, i) {
10992
- var _helper_lastResults;
10993
- return {
10994
- insightsMethod: 'clickedObjectIDsAfterSearch',
10995
- widgetType: widgetType,
10996
- eventType: eventType,
10997
- payload: _object_spread({
10998
- eventName: eventName || 'Hit Clicked',
10999
- index: ((_helper_lastResults = helper.lastResults) === null || _helper_lastResults === void 0 ? void 0 : _helper_lastResults.index) || helper.state.index,
11000
- queryID: queryID,
11001
- objectIDs: objectIDsByChunk[i],
11002
- positions: positionsByChunk[i]
11003
- }, additionalData),
11004
- hits: batch,
11005
- eventModifier: eventModifier
11006
- };
11007
- });
11008
- } else if (eventType === 'conversion') {
11009
- return hitsChunks.map(function(batch, i) {
11010
- var _helper_lastResults;
11011
- return {
11012
- insightsMethod: 'convertedObjectIDsAfterSearch',
11013
- widgetType: widgetType,
11014
- eventType: eventType,
11015
- payload: _object_spread({
11016
- eventName: eventName || 'Hit Converted',
11017
- index: ((_helper_lastResults = helper.lastResults) === null || _helper_lastResults === void 0 ? void 0 : _helper_lastResults.index) || helper.state.index,
11018
- queryID: queryID,
11019
- objectIDs: objectIDsByChunk[i]
11020
- }, additionalData),
11021
- hits: batch,
11022
- eventModifier: eventModifier
11023
- };
11024
- });
11025
- } else {
11026
- return [];
11027
- }
11028
- }
11029
- function createSendEventForHits(param) {
11030
- var instantSearchInstance = param.instantSearchInstance, helper = param.helper, widgetType = param.widgetType;
11031
- var sentEvents = {};
11032
- var timer = undefined;
11033
- var sendEventForHits = function sendEventForHits() {
11034
- for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
11035
- args[_key] = arguments[_key];
11036
- }
11037
- var payloads = _buildEventPayloadsForHits({
11038
- widgetType: widgetType,
11039
- helper: helper,
11040
- methodName: 'sendEvent',
11041
- args: args,
11042
- instantSearchInstance: instantSearchInstance
11043
- });
11044
- payloads.forEach(function(payload) {
11045
- if (payload.eventType === 'click' && payload.eventModifier === 'internal' && sentEvents[payload.eventType]) {
11046
- return;
11047
- }
11048
- sentEvents[payload.eventType] = true;
11049
- instantSearchInstance.sendEventToInsights(payload);
11050
- });
11051
- clearTimeout(timer);
11052
- timer = setTimeout(function() {
11053
- sentEvents = {};
11054
- }, 0);
11055
- };
11056
- return sendEventForHits;
11057
- }
11058
- function createBindEventForHits(param) {
11059
- var helper = param.helper, widgetType = param.widgetType, instantSearchInstance = param.instantSearchInstance;
11060
- var bindEventForHits = function bindEventForHits() {
11061
- for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
11062
- args[_key] = arguments[_key];
11063
- }
11064
- var payloads = _buildEventPayloadsForHits({
11065
- widgetType: widgetType,
11066
- helper: helper,
11067
- methodName: 'bindEvent',
11068
- args: args,
11069
- instantSearchInstance: instantSearchInstance
11070
- });
11071
- return payloads.length ? "data-insights-event=".concat(serializePayload(payloads)) : '';
11072
- };
11073
- return bindEventForHits;
11074
- }
11075
-
11076
- function addQueryID(hits, queryID) {
11077
- if (!queryID) {
11078
- return hits;
11079
- }
11080
- return hits.map(function(hit) {
11081
- return _object_spread_props(_object_spread({}, hit), {
11082
- __queryID: queryID
11083
- });
11084
- });
11085
- }
11086
-
11087
- function addAbsolutePosition(hits, page, hitsPerPage) {
11088
- return hits.map(function(hit, idx) {
11089
- return _object_spread_props(_object_spread({}, hit), {
11090
- __position: hitsPerPage * page + idx + 1
11091
- });
11092
- });
11093
- }
11094
-
11095
11893
  var withUsage$p = createDocumentationMessageGenerator({
11096
11894
  name: 'autocomplete',
11097
11895
  connector: true
@@ -11956,6 +12754,7 @@
11956
12754
  var currentTextPartId;
11957
12755
  var currentReasoningPartId;
11958
12756
  var toolRawInputByCallId = {};
12757
+ var toolRawOutputByCallId = {};
11959
12758
  // Promise chain for handling tool calls that return promises
11960
12759
  var pendingToolCall = Promise.resolve();
11961
12760
  return new Promise(function(resolve) {
@@ -12200,24 +12999,69 @@
12200
12999
  }
12201
13000
  break;
12202
13001
  }
12203
- case 'tool-output-available':
13002
+ case 'data-tool-output-delta':
12204
13003
  {
13004
+ var _ref3, _ref4;
12205
13005
  if (!currentMessage) break;
13006
+ var _chunk_data = chunk.data, toolCallId = _chunk_data.toolCallId, toolName1 = _chunk_data.toolName, delta = _chunk_data.delta;
12206
13007
  var toolIndex1 = currentMessage.parts.findIndex(function(p) {
12207
- return 'toolCallId' in p && p.toolCallId === chunk.toolCallId;
13008
+ return 'toolCallId' in p && p.toolCallId === toolCallId;
13009
+ });
13010
+ var existingPart1 = toolIndex1 >= 0 ? currentMessage.parts[toolIndex1] : null;
13011
+ var previousRawOutput = (_ref3 = (_ref4 = existingPart1 === null || existingPart1 === void 0 ? void 0 : existingPart1.rawOutput) !== null && _ref4 !== void 0 ? _ref4 : toolRawOutputByCallId[toolCallId]) !== null && _ref3 !== void 0 ? _ref3 : '';
13012
+ var nextRawOutput = "".concat(previousRawOutput).concat(delta);
13013
+ toolRawOutputByCallId[toolCallId] = nextRawOutput;
13014
+ var parsedOutput = parseToolInputDelta(nextRawOutput, existingPart1 === null || existingPart1 === void 0 ? void 0 : existingPart1.output);
13015
+ var nextToolPart1 = _object_spread_props(_object_spread({}, existingPart1 !== null && existingPart1 !== void 0 ? existingPart1 : {
13016
+ type: "tool-".concat(toolName1),
13017
+ toolCallId: toolCallId,
13018
+ input: undefined
13019
+ }), {
13020
+ state: 'output-available',
13021
+ output: parsedOutput,
13022
+ rawOutput: nextRawOutput,
13023
+ preliminary: true
12208
13024
  });
12209
13025
  if (toolIndex1 >= 0) {
13026
+ var updatedParts6 = _to_consumable_array(currentMessage.parts);
13027
+ updatedParts6[toolIndex1] = nextToolPart1;
13028
+ currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13029
+ parts: updatedParts6
13030
+ });
13031
+ } else {
13032
+ currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13033
+ parts: _to_consumable_array(currentMessage.parts).concat([
13034
+ nextToolPart1
13035
+ ])
13036
+ });
13037
+ }
13038
+ _this.state.replaceMessage(currentMessageIndex, currentMessage);
13039
+ break;
13040
+ }
13041
+ case 'tool-output-available':
13042
+ {
13043
+ if (!currentMessage) break;
13044
+ var toolIndex2 = currentMessage.parts.findIndex(function(p) {
13045
+ return 'toolCallId' in p && p.toolCallId === chunk.toolCallId;
13046
+ });
13047
+ if (toolIndex2 >= 0) {
12210
13048
  delete toolRawInputByCallId[chunk.toolCallId];
12211
- var updatedParts6 = _to_consumable_array(currentMessage.parts);
12212
- var existingPart1 = updatedParts6[toolIndex1];
12213
- updatedParts6[toolIndex1] = _object_spread_props(_object_spread({}, existingPart1), {
13049
+ delete toolRawOutputByCallId[chunk.toolCallId];
13050
+ var updatedParts7 = _to_consumable_array(currentMessage.parts);
13051
+ var existingPart2 = updatedParts7[toolIndex2];
13052
+ // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
13053
+ existingPart2.rawOutput;
13054
+ var rest = _object_without_properties(existingPart2, [
13055
+ "rawOutput"
13056
+ ]);
13057
+ updatedParts7[toolIndex2] = _object_spread_props(_object_spread({}, rest), {
12214
13058
  state: 'output-available',
12215
13059
  output: chunk.output,
12216
13060
  callProviderMetadata: chunk.callProviderMetadata,
12217
13061
  preliminary: chunk.preliminary
12218
13062
  });
12219
13063
  currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
12220
- parts: updatedParts6
13064
+ parts: updatedParts7
12221
13065
  });
12222
13066
  _this.state.replaceMessage(currentMessageIndex, currentMessage);
12223
13067
  }
@@ -12226,22 +13070,30 @@
12226
13070
  case 'tool-error':
12227
13071
  {
12228
13072
  if (!currentMessage) break;
12229
- var toolIndex2 = currentMessage.parts.findIndex(function(p) {
13073
+ var toolIndex3 = currentMessage.parts.findIndex(function(p) {
12230
13074
  return 'toolCallId' in p && p.toolCallId === chunk.toolCallId;
12231
13075
  });
12232
- if (toolIndex2 >= 0) {
13076
+ if (toolIndex3 >= 0) {
12233
13077
  var _chunk_input;
12234
13078
  delete toolRawInputByCallId[chunk.toolCallId];
12235
- var updatedParts7 = _to_consumable_array(currentMessage.parts);
12236
- var existingPart2 = updatedParts7[toolIndex2];
12237
- updatedParts7[toolIndex2] = _object_spread_props(_object_spread({}, existingPart2), {
13079
+ delete toolRawOutputByCallId[chunk.toolCallId];
13080
+ var updatedParts8 = _to_consumable_array(currentMessage.parts);
13081
+ var existingPart3 = updatedParts8[toolIndex3];
13082
+ // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
13083
+ existingPart3.rawOutput; // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
13084
+ existingPart3.preliminary;
13085
+ var rest1 = _object_without_properties(existingPart3, [
13086
+ "rawOutput",
13087
+ "preliminary"
13088
+ ]);
13089
+ updatedParts8[toolIndex3] = _object_spread_props(_object_spread({}, rest1), {
12238
13090
  state: 'output-error',
12239
13091
  errorText: chunk.errorText,
12240
- input: (_chunk_input = chunk.input) !== null && _chunk_input !== void 0 ? _chunk_input : existingPart2.input,
13092
+ input: (_chunk_input = chunk.input) !== null && _chunk_input !== void 0 ? _chunk_input : existingPart3.input,
12241
13093
  callProviderMetadata: chunk.callProviderMetadata
12242
13094
  });
12243
13095
  currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
12244
- parts: updatedParts7
13096
+ parts: updatedParts8
12245
13097
  });
12246
13098
  _this.state.replaceMessage(currentMessageIndex, currentMessage);
12247
13099
  }
@@ -12700,272 +13552,96 @@
12700
13552
  throw new Error("HTTP error: ".concat(response.status, " ").concat(response.statusText));
12701
13553
  }
12702
13554
  if (!response.body) {
12703
- throw new Error('Response body is empty');
12704
- }
12705
- return _this.processResponseStream(response.body);
12706
- });
12707
- });
12708
- });
12709
- }
12710
- },
12711
- {
12712
- key: "reconnectToStream",
12713
- value: function reconnectToStream(param) {
12714
- var _this = this;
12715
- var chatId = param.chatId, requestHeaders = param.headers, requestBody = param.body;
12716
- var _this_fetch;
12717
- var fetchFn = (_this_fetch = this.fetch) !== null && _this_fetch !== void 0 ? _this_fetch : fetch;
12718
- // Resolve configurable values
12719
- return Promise.all([
12720
- resolveValue(this.credentials),
12721
- resolveValue(this.headers),
12722
- resolveValue(this.body)
12723
- ]).then(function(param) {
12724
- var _param = _sliced_to_array(param, 3), resolvedCredentials = _param[0], resolvedHeaders = _param[1], resolvedBody = _param[2];
12725
- // Build default request options
12726
- var api = _this.api;
12727
- var headers = _object_spread({}, _instanceof(resolvedHeaders, Headers) ? Object.fromEntries(resolvedHeaders.entries()) : resolvedHeaders, _instanceof(requestHeaders, Headers) ? Object.fromEntries(requestHeaders.entries()) : requestHeaders);
12728
- var credentials = resolvedCredentials;
12729
- // Apply custom preparation if provided
12730
- var prepareRequestBody = _object_spread({}, resolvedBody, requestBody);
12731
- var preparePromise = _this.prepareReconnectToStreamRequest ? Promise.resolve(_this.prepareReconnectToStreamRequest({
12732
- id: chatId,
12733
- requestMetadata: undefined,
12734
- body: prepareRequestBody,
12735
- credentials: resolvedCredentials,
12736
- headers: resolvedHeaders,
12737
- api: _this.api
12738
- })) : Promise.resolve(null);
12739
- return preparePromise.then(function(prepared) {
12740
- if (prepared) {
12741
- if (prepared.api) api = prepared.api;
12742
- if (prepared.headers) {
12743
- headers = _instanceof(prepared.headers, Headers) ? Object.fromEntries(prepared.headers.entries()) : prepared.headers;
12744
- }
12745
- if (prepared.credentials) credentials = prepared.credentials;
12746
- }
12747
- // GET request for reconnection
12748
- return fetchFn("".concat(api, "?chatId=").concat(chatId), {
12749
- method: 'GET',
12750
- headers: headers,
12751
- credentials: credentials
12752
- }).then(function(response) {
12753
- if (!response.ok) {
12754
- // 404 means no stream to reconnect to, which is not an error
12755
- if (response.status === 404) {
12756
- return null;
12757
- }
12758
- throw new Error("HTTP error: ".concat(response.status, " ").concat(response.statusText));
12759
- }
12760
- if (!response.body) {
12761
- return null;
12762
- }
12763
- return _this.processResponseStream(response.body);
12764
- });
12765
- });
12766
- });
12767
- }
12768
- }
12769
- ]);
12770
- return HttpChatTransport;
12771
- }();
12772
- /**
12773
- * Default chat transport implementation using NDJSON streaming.
12774
- */ var DefaultChatTransport = /*#__PURE__*/ function(HttpChatTransport) {
12775
- _inherits(DefaultChatTransport, HttpChatTransport);
12776
- function DefaultChatTransport() {
12777
- var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
12778
- _class_call_check(this, DefaultChatTransport);
12779
- return _call_super(this, DefaultChatTransport, [
12780
- options
12781
- ]);
12782
- }
12783
- _create_class(DefaultChatTransport, [
12784
- {
12785
- key: "processResponseStream",
12786
- value: function processResponseStream(stream) {
12787
- return parseJsonEventStream(stream);
12788
- }
12789
- }
12790
- ]);
12791
- return DefaultChatTransport;
12792
- }(HttpChatTransport);
12793
-
12794
- function sendChatMessageFeedback(param) {
12795
- var agentId = param.agentId, vote = param.vote, messageId = param.messageId, appId = param.appId, apiKey = param.apiKey;
12796
- return fetch("https://".concat(appId, ".algolia.net/agent-studio/1/feedback"), {
12797
- method: 'POST',
12798
- body: JSON.stringify({
12799
- messageId: messageId,
12800
- agentId: agentId,
12801
- vote: vote
12802
- }),
12803
- headers: {
12804
- 'x-algolia-application-id': appId,
12805
- 'x-algolia-api-key': apiKey,
12806
- 'content-type': 'application/json'
12807
- }
12808
- }).then(function(response) {
12809
- if (response.status >= 300) {
12810
- return response.json().then(function(data) {
12811
- throw new Error("Feedback request failed with status ".concat(response.status, ": ").concat(data.message));
12812
- });
12813
- }
12814
- return response.json();
12815
- });
12816
- }
12817
-
12818
- /**
12819
- * Clears the refinements of a SearchParameters object based on rules provided.
12820
- * The included attributes list is applied before the excluded attributes list. If the list
12821
- * is not provided, this list of all the currently refined attributes is used as included attributes.
12822
- * @returns search parameters with refinements cleared
12823
- */ function clearRefinements(param) {
12824
- var helper = param.helper, _param_attributesToClear = param.attributesToClear, attributesToClear = _param_attributesToClear === void 0 ? [] : _param_attributesToClear;
12825
- var finalState = helper.state.setPage(0);
12826
- finalState = attributesToClear.reduce(function(state, attribute) {
12827
- if (finalState.isNumericRefined(attribute)) {
12828
- return state.removeNumericRefinement(attribute);
12829
- }
12830
- if (finalState.isHierarchicalFacet(attribute)) {
12831
- return state.removeHierarchicalFacetRefinement(attribute);
12832
- }
12833
- if (finalState.isDisjunctiveFacet(attribute)) {
12834
- return state.removeDisjunctiveFacetRefinement(attribute);
12835
- }
12836
- if (finalState.isConjunctiveFacet(attribute)) {
12837
- return state.removeFacetRefinement(attribute);
12838
- }
12839
- return state;
12840
- }, finalState);
12841
- if (attributesToClear.indexOf('query') !== -1) {
12842
- finalState = finalState.setQuery('');
12843
- }
12844
- return finalState;
12845
- }
12846
-
12847
- function unescapeFacetValue(value) {
12848
- if (typeof value === 'string') {
12849
- return value.replace(/^\\-/, '-');
12850
- }
12851
- return value;
12852
- }
12853
- function escapeFacetValue(value) {
12854
- if (typeof value === 'number' && value < 0 || typeof value === 'string') {
12855
- return String(value).replace(/^-/, '\\-');
12856
- }
12857
- return value;
12858
- }
12859
-
12860
- function getRefinement(state, type, attribute, name) {
12861
- var resultsFacets = arguments.length > 4 && arguments[4] !== void 0 ? arguments[4] : [];
12862
- var res = {
12863
- type: type,
12864
- attribute: attribute,
12865
- name: name,
12866
- escapedValue: escapeFacetValue(name)
12867
- };
12868
- var facet = find(resultsFacets, function(resultsFacet) {
12869
- return resultsFacet.name === attribute;
12870
- });
12871
- var count;
12872
- if (type === 'hierarchical') {
12873
- var _loop = function _loop(i) {
12874
- facet = facet && facet.data && find(Object.keys(facet.data).map(getFacetRefinement(facet.data)), function(refinement) {
12875
- return refinement.name === nameParts[i];
12876
- });
12877
- };
12878
- var facetDeclaration = state.getHierarchicalFacetByName(attribute);
12879
- var nameParts = name.split(facetDeclaration.separator);
12880
- var getFacetRefinement = function getFacetRefinement(facetData) {
12881
- return function(refinementKey) {
12882
- return facetData[refinementKey];
12883
- };
12884
- };
12885
- for(var i = 0; facet !== undefined && i < nameParts.length; ++i)_loop(i);
12886
- count = facet && facet.count;
12887
- } else {
12888
- count = facet && facet.data && facet.data[res.name];
12889
- }
12890
- if (count !== undefined) {
12891
- res.count = count;
12892
- }
12893
- if (facet && facet.exhaustive !== undefined) {
12894
- res.exhaustive = facet.exhaustive;
12895
- }
12896
- return res;
12897
- }
12898
- function getRefinements(_results, state) {
12899
- var includesQuery = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : false;
12900
- var results = _results || {};
12901
- var refinements = [];
12902
- var _state_facetsRefinements = state.facetsRefinements, facetsRefinements = _state_facetsRefinements === void 0 ? {} : _state_facetsRefinements, _state_facetsExcludes = state.facetsExcludes, facetsExcludes = _state_facetsExcludes === void 0 ? {} : _state_facetsExcludes, _state_disjunctiveFacetsRefinements = state.disjunctiveFacetsRefinements, disjunctiveFacetsRefinements = _state_disjunctiveFacetsRefinements === void 0 ? {} : _state_disjunctiveFacetsRefinements, _state_hierarchicalFacetsRefinements = state.hierarchicalFacetsRefinements, hierarchicalFacetsRefinements = _state_hierarchicalFacetsRefinements === void 0 ? {} : _state_hierarchicalFacetsRefinements, _state_numericRefinements = state.numericRefinements, numericRefinements = _state_numericRefinements === void 0 ? {} : _state_numericRefinements, _state_tagRefinements = state.tagRefinements, tagRefinements = _state_tagRefinements === void 0 ? [] : _state_tagRefinements;
12903
- Object.keys(facetsRefinements).forEach(function(attribute) {
12904
- var refinementNames = facetsRefinements[attribute];
12905
- refinementNames.forEach(function(refinementName) {
12906
- refinements.push(getRefinement(state, 'facet', attribute, refinementName, results.facets));
12907
- });
12908
- });
12909
- Object.keys(facetsExcludes).forEach(function(attribute) {
12910
- var refinementNames = facetsExcludes[attribute];
12911
- refinementNames.forEach(function(refinementName) {
12912
- refinements.push({
12913
- type: 'exclude',
12914
- attribute: attribute,
12915
- name: refinementName,
12916
- exclude: true
12917
- });
12918
- });
12919
- });
12920
- Object.keys(disjunctiveFacetsRefinements).forEach(function(attribute) {
12921
- var refinementNames = disjunctiveFacetsRefinements[attribute];
12922
- refinementNames.forEach(function(refinementName) {
12923
- refinements.push(getRefinement(state, 'disjunctive', attribute, // they can be escaped on negative numeric values with `escapeFacetValue`.
12924
- unescapeFacetValue(refinementName), results.disjunctiveFacets));
12925
- });
12926
- });
12927
- Object.keys(hierarchicalFacetsRefinements).forEach(function(attribute) {
12928
- var refinementNames = hierarchicalFacetsRefinements[attribute];
12929
- refinementNames.forEach(function(refinement) {
12930
- refinements.push(getRefinement(state, 'hierarchical', attribute, refinement, results.hierarchicalFacets));
12931
- });
12932
- });
12933
- Object.keys(numericRefinements).forEach(function(attribute) {
12934
- var operators = numericRefinements[attribute];
12935
- Object.keys(operators).forEach(function(operatorOriginal) {
12936
- var operator = operatorOriginal;
12937
- var valueOrValues = operators[operator];
12938
- var refinementNames = Array.isArray(valueOrValues) ? valueOrValues : [
12939
- valueOrValues
12940
- ];
12941
- refinementNames.forEach(function(refinementName) {
12942
- refinements.push({
12943
- type: 'numeric',
12944
- attribute: attribute,
12945
- name: "".concat(refinementName),
12946
- numericValue: refinementName,
12947
- operator: operator
13555
+ throw new Error('Response body is empty');
13556
+ }
13557
+ return _this.processResponseStream(response.body);
13558
+ });
13559
+ });
12948
13560
  });
12949
- });
12950
- });
12951
- });
12952
- tagRefinements.forEach(function(refinementName) {
12953
- refinements.push({
12954
- type: 'tag',
12955
- attribute: '_tags',
12956
- name: refinementName
12957
- });
12958
- });
12959
- if (includesQuery && state.query && state.query.trim()) {
12960
- refinements.push({
12961
- attribute: 'query',
12962
- type: 'query',
12963
- name: state.query,
12964
- query: state.query
12965
- });
13561
+ }
13562
+ },
13563
+ {
13564
+ key: "reconnectToStream",
13565
+ value: function reconnectToStream(param) {
13566
+ var _this = this;
13567
+ var chatId = param.chatId, requestHeaders = param.headers, requestBody = param.body;
13568
+ var _this_fetch;
13569
+ var fetchFn = (_this_fetch = this.fetch) !== null && _this_fetch !== void 0 ? _this_fetch : fetch;
13570
+ // Resolve configurable values
13571
+ return Promise.all([
13572
+ resolveValue(this.credentials),
13573
+ resolveValue(this.headers),
13574
+ resolveValue(this.body)
13575
+ ]).then(function(param) {
13576
+ var _param = _sliced_to_array(param, 3), resolvedCredentials = _param[0], resolvedHeaders = _param[1], resolvedBody = _param[2];
13577
+ // Build default request options
13578
+ var api = _this.api;
13579
+ var headers = _object_spread({}, _instanceof(resolvedHeaders, Headers) ? Object.fromEntries(resolvedHeaders.entries()) : resolvedHeaders, _instanceof(requestHeaders, Headers) ? Object.fromEntries(requestHeaders.entries()) : requestHeaders);
13580
+ var credentials = resolvedCredentials;
13581
+ // Apply custom preparation if provided
13582
+ var prepareRequestBody = _object_spread({}, resolvedBody, requestBody);
13583
+ var preparePromise = _this.prepareReconnectToStreamRequest ? Promise.resolve(_this.prepareReconnectToStreamRequest({
13584
+ id: chatId,
13585
+ requestMetadata: undefined,
13586
+ body: prepareRequestBody,
13587
+ credentials: resolvedCredentials,
13588
+ headers: resolvedHeaders,
13589
+ api: _this.api
13590
+ })) : Promise.resolve(null);
13591
+ return preparePromise.then(function(prepared) {
13592
+ if (prepared) {
13593
+ if (prepared.api) api = prepared.api;
13594
+ if (prepared.headers) {
13595
+ headers = _instanceof(prepared.headers, Headers) ? Object.fromEntries(prepared.headers.entries()) : prepared.headers;
13596
+ }
13597
+ if (prepared.credentials) credentials = prepared.credentials;
13598
+ }
13599
+ // GET request for reconnection
13600
+ return fetchFn("".concat(api, "?chatId=").concat(chatId), {
13601
+ method: 'GET',
13602
+ headers: headers,
13603
+ credentials: credentials
13604
+ }).then(function(response) {
13605
+ if (!response.ok) {
13606
+ // 404 means no stream to reconnect to, which is not an error
13607
+ if (response.status === 404) {
13608
+ return null;
13609
+ }
13610
+ throw new Error("HTTP error: ".concat(response.status, " ").concat(response.statusText));
13611
+ }
13612
+ if (!response.body) {
13613
+ return null;
13614
+ }
13615
+ return _this.processResponseStream(response.body);
13616
+ });
13617
+ });
13618
+ });
13619
+ }
13620
+ }
13621
+ ]);
13622
+ return HttpChatTransport;
13623
+ }();
13624
+ /**
13625
+ * Default chat transport implementation using NDJSON streaming.
13626
+ */ var DefaultChatTransport = /*#__PURE__*/ function(HttpChatTransport) {
13627
+ _inherits(DefaultChatTransport, HttpChatTransport);
13628
+ function DefaultChatTransport() {
13629
+ var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
13630
+ _class_call_check(this, DefaultChatTransport);
13631
+ return _call_super(this, DefaultChatTransport, [
13632
+ options
13633
+ ]);
12966
13634
  }
12967
- return refinements;
12968
- }
13635
+ _create_class(DefaultChatTransport, [
13636
+ {
13637
+ key: "processResponseStream",
13638
+ value: function processResponseStream(stream) {
13639
+ return parseJsonEventStream(stream);
13640
+ }
13641
+ }
13642
+ ]);
13643
+ return DefaultChatTransport;
13644
+ }(HttpChatTransport);
12969
13645
 
12970
13646
  var withUsage$n = createDocumentationMessageGenerator({
12971
13647
  name: 'chat',
@@ -13785,67 +14461,6 @@
13785
14461
  return useConnector(connectFrequentlyBoughtTogether, props, additionalWidgetProperties);
13786
14462
  }
13787
14463
 
13788
- var latLngRegExp = /^(-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)$/;
13789
- function aroundLatLngToPosition(value) {
13790
- var pattern = value.match(latLngRegExp);
13791
- // Since the value provided is the one send with the request, the API should
13792
- // throw an error due to the wrong format. So throw an error should be safe.
13793
- if (!pattern) {
13794
- throw new Error('Invalid value for "aroundLatLng" parameter: "'.concat(value, '"'));
13795
- }
13796
- return {
13797
- lat: parseFloat(pattern[1]),
13798
- lng: parseFloat(pattern[2])
13799
- };
13800
- }
13801
- function insideBoundingBoxArrayToBoundingBox(value) {
13802
- var _value = _sliced_to_array(value, 1), tmp = _value[0], _ref = _sliced_to_array(tmp === void 0 ? [
13803
- undefined,
13804
- undefined,
13805
- undefined,
13806
- undefined
13807
- ] : tmp, 4), neLat = _ref[0], neLng = _ref[1], swLat = _ref[2], swLng = _ref[3];
13808
- // Since the value provided is the one send with the request, the API should
13809
- // throw an error due to the wrong format. So throw an error should be safe.
13810
- if (!neLat || !neLng || !swLat || !swLng) {
13811
- throw new Error('Invalid value for "insideBoundingBox" parameter: ['.concat(value, "]"));
13812
- }
13813
- return {
13814
- northEast: {
13815
- lat: neLat,
13816
- lng: neLng
13817
- },
13818
- southWest: {
13819
- lat: swLat,
13820
- lng: swLng
13821
- }
13822
- };
13823
- }
13824
- function insideBoundingBoxStringToBoundingBox(value) {
13825
- var _value_split_map = _sliced_to_array(value.split(',').map(parseFloat), 4), neLat = _value_split_map[0], neLng = _value_split_map[1], swLat = _value_split_map[2], swLng = _value_split_map[3];
13826
- // Since the value provided is the one send with the request, the API should
13827
- // throw an error due to the wrong format. So throw an error should be safe.
13828
- if (!neLat || !neLng || !swLat || !swLng) {
13829
- throw new Error('Invalid value for "insideBoundingBox" parameter: "'.concat(value, '"'));
13830
- }
13831
- return {
13832
- northEast: {
13833
- lat: neLat,
13834
- lng: neLng
13835
- },
13836
- southWest: {
13837
- lat: swLat,
13838
- lng: swLng
13839
- }
13840
- };
13841
- }
13842
- function insideBoundingBoxToBoundingBox(value) {
13843
- if (Array.isArray(value)) {
13844
- return insideBoundingBoxArrayToBoundingBox(value);
13845
- }
13846
- return insideBoundingBoxStringToBoundingBox(value);
13847
- }
13848
-
13849
14464
  var withUsage$j = createDocumentationMessageGenerator({
13850
14465
  name: 'geo-search',
13851
14466
  connector: true
@@ -14043,51 +14658,6 @@
14043
14658
  return useConnector(connectGeoSearch, props, additionalWidgetProperties);
14044
14659
  }
14045
14660
 
14046
- function isFacetRefined(helper, facet, value) {
14047
- if (helper.state.isHierarchicalFacet(facet)) {
14048
- return helper.state.isHierarchicalFacetRefined(facet, value);
14049
- } else if (helper.state.isConjunctiveFacet(facet)) {
14050
- return helper.state.isFacetRefined(facet, value);
14051
- } else {
14052
- return helper.state.isDisjunctiveFacetRefined(facet, value);
14053
- }
14054
- }
14055
-
14056
- function createSendEventForFacet(param) {
14057
- var instantSearchInstance = param.instantSearchInstance, helper = param.helper, attr = param.attribute, widgetType = param.widgetType;
14058
- var sendEventForFacet = function sendEventForFacet() {
14059
- for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
14060
- args[_key] = arguments[_key];
14061
- }
14062
- var _args = _sliced_to_array(args, 4), facetValue = _args[1], tmp = _args[2], eventName = tmp === void 0 ? 'Filter Applied' : tmp, tmp1 = _args[3], additionalData = tmp1 === void 0 ? {} : tmp1;
14063
- var _args__split = _sliced_to_array(args[0].split(':'), 2), eventType = _args__split[0], eventModifier = _args__split[1];
14064
- var attribute = typeof attr === 'string' ? attr : attr(facetValue);
14065
- if (args.length === 1 && _type_of(args[0]) === 'object') {
14066
- instantSearchInstance.sendEventToInsights(args[0]);
14067
- } else if (eventType === 'click' && args.length >= 2 && args.length <= 4) {
14068
- if (!isFacetRefined(helper, attribute, facetValue)) {
14069
- var _helper_lastResults;
14070
- // send event only when the facet is being checked "ON"
14071
- instantSearchInstance.sendEventToInsights({
14072
- insightsMethod: 'clickedFilters',
14073
- widgetType: widgetType,
14074
- eventType: eventType,
14075
- eventModifier: eventModifier,
14076
- payload: _object_spread({
14077
- eventName: eventName,
14078
- index: ((_helper_lastResults = helper.lastResults) === null || _helper_lastResults === void 0 ? void 0 : _helper_lastResults.index) || helper.state.index,
14079
- filters: [
14080
- "".concat(attribute, ":").concat(facetValue)
14081
- ]
14082
- }, additionalData),
14083
- attribute: attribute
14084
- });
14085
- }
14086
- } else ;
14087
- };
14088
- return sendEventForFacet;
14089
- }
14090
-
14091
14661
  var withUsage$i = createDocumentationMessageGenerator({
14092
14662
  name: 'hierarchical-menu',
14093
14663
  connector: true
@@ -14544,17 +15114,6 @@
14544
15114
  return useConnector(connectHitsPerPage, props, additionalWidgetProperties);
14545
15115
  }
14546
15116
 
14547
- /**
14548
- * Recurse over all child indices
14549
- */ function walkIndex(indexWidget, callback) {
14550
- callback(indexWidget);
14551
- indexWidget.getWidgets().forEach(function(widget) {
14552
- if (isIndexWidget(widget)) {
14553
- walkIndex(widget, callback);
14554
- }
14555
- });
14556
- }
14557
-
14558
15117
  var withUsage$f = createDocumentationMessageGenerator({
14559
15118
  name: 'infinite-hits',
14560
15119
  connector: true
@@ -14723,19 +15282,16 @@
14723
15282
  });
14724
15283
  /*
14725
15284
  With dynamic widgets, facets are not included in the state before their relevant widgets are mounted. Until then, we need to bail out of writing this incomplete state representation in cache.
14726
- */ var hasDynamicWidgets = false;
15285
+ */ var hasTwoPassWidgets = false;
14727
15286
  walkIndex(instantSearchInstance.mainIndex, function(indexWidget) {
14728
- if (!hasDynamicWidgets && indexWidget.getWidgets().some(function(param) {
14729
- var $$type = param.$$type;
14730
- return $$type === 'ais.dynamicWidgets';
14731
- })) {
14732
- hasDynamicWidgets = true;
15287
+ if (!hasTwoPassWidgets && indexWidget.getWidgets().some(isTwoPassWidget)) {
15288
+ hasTwoPassWidgets = true;
14733
15289
  }
14734
15290
  });
14735
15291
  var hasNoFacets = !((_state_disjunctiveFacets = state.disjunctiveFacets) === null || _state_disjunctiveFacets === void 0 ? void 0 : _state_disjunctiveFacets.length) && !(state.facets || []).filter(function(f) {
14736
15292
  return f !== '*';
14737
15293
  }).length && !((_state_hierarchicalFacets = state.hierarchicalFacets) === null || _state_hierarchicalFacets === void 0 ? void 0 : _state_hierarchicalFacets.length);
14738
- if (cachedHits[page] === undefined && !results.__isArtificial && instantSearchInstance.status === 'idle' && !(hasDynamicWidgets && hasNoFacets)) {
15294
+ if (cachedHits[page] === undefined && !results.__isArtificial && instantSearchInstance.status === 'idle' && !(hasTwoPassWidgets && hasNoFacets)) {
14739
15295
  cachedHits[page] = transformedHits;
14740
15296
  cache.write({
14741
15297
  state: normalizeState(state),
@@ -14996,14 +15552,6 @@
14996
15552
  return useConnector(connectMenu, props, additionalWidgetProperties);
14997
15553
  }
14998
15554
 
14999
- // This is the `Number.isFinite()` polyfill recommended by MDN.
15000
- // We do not provide any tests for this function.
15001
- // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite#Polyfill
15002
- // @MAJOR Replace with the native `Number.isFinite` method
15003
- function isFiniteNumber(value) {
15004
- return typeof value === 'number' && isFinite(value);
15005
- }
15006
-
15007
15555
  var withUsage$d = createDocumentationMessageGenerator({
15008
15556
  name: 'numeric-menu',
15009
15557
  connector: true
@@ -15264,21 +15812,6 @@
15264
15812
  return useConnector(connectNumericMenu, props, additionalWidgetProperties);
15265
15813
  }
15266
15814
 
15267
- function range(param) {
15268
- var _param_start = param.start, start = _param_start === void 0 ? 0 : _param_start, end = param.end, _param_step = param.step, step = _param_step === void 0 ? 1 : _param_step;
15269
- // We can't divide by 0 so we re-assign the step to 1 if it happens.
15270
- var limitStep = step === 0 ? 1 : step;
15271
- // In some cases the array to create has a decimal length.
15272
- // We therefore need to round the value.
15273
- // Example:
15274
- // { start: 1, end: 5000, step: 500 }
15275
- // => Array length = (5000 - 1) / 500 = 9.998
15276
- var arrayLength = Math.round((end - start) / limitStep);
15277
- return _to_consumable_array(Array(arrayLength)).map(function(_, current) {
15278
- return start + current * limitStep;
15279
- });
15280
- }
15281
-
15282
15815
  var Paginator = /*#__PURE__*/ function() {
15283
15816
  function Paginator(params) {
15284
15817
  _class_call_check(this, Paginator);
@@ -15455,12 +15988,6 @@
15455
15988
  return useConnector(connectPagination, props, additionalWidgetProperties);
15456
15989
  }
15457
15990
 
15458
- function toArray(value) {
15459
- return Array.isArray(value) ? value : [
15460
- value
15461
- ];
15462
- }
15463
-
15464
15991
  function usePoweredBy() {
15465
15992
  var hostname = safelyRunOnBrowser(function(param) {
15466
15993
  var window = param.window;
@@ -16451,7 +16978,8 @@
16451
16978
  },
16452
16979
  getWidgetSearchParameters: function getWidgetSearchParameters(searchParameters, param) {
16453
16980
  var uiState = param.uiState;
16454
- var sortByValue = uiState.sortBy || connectorState.initialValue || searchParameters.index;
16981
+ var isUiStateSortByInItems = !uiState.sortBy || Object.prototype.hasOwnProperty.call(connectorState.itemsLookup, uiState.sortBy);
16982
+ var sortByValue = (isUiStateSortByInItems ? uiState.sortBy : undefined) || connectorState.initialValue || searchParameters.index;
16455
16983
  if (isValidStrategy(connectorState.itemsLookup, sortByValue)) {
16456
16984
  var item = connectorState.itemsLookup[sortByValue];
16457
16985
  // Strategy-based: set the sortBy parameter for composition API
@@ -17552,13 +18080,19 @@
17552
18080
  var resultsCount = (searchResults === null || searchResults === void 0 ? void 0 : (_searchResults__rawResults = searchResults._rawResults) === null || _searchResults__rawResults === void 0 ? void 0 : _searchResults__rawResults.length) || 0;
17553
18081
  var requestParams = resultsCount ? requestParamsList === null || requestParamsList === void 0 ? void 0 : requestParamsList.slice(requestParamsIndex, requestParamsIndex + resultsCount) : [];
17554
18082
  requestParamsIndex += resultsCount;
17555
- initialResults[widget.getIndexId()] = _object_spread({}, searchResults && {
18083
+ initialResults[widget.getIndexId()] = _object_spread({}, searchResults && _object_spread({
17556
18084
  state: _object_spread_props(_object_spread({}, searchResults._state), {
17557
18085
  clickAnalytics: requestParams === null || requestParams === void 0 ? void 0 : (_requestParams_ = requestParams[0]) === null || _requestParams_ === void 0 ? void 0 : _requestParams_.clickAnalytics,
17558
18086
  userToken: requestParams === null || requestParams === void 0 ? void 0 : (_requestParams_1 = requestParams[0]) === null || _requestParams_1 === void 0 ? void 0 : _requestParams_1.userToken
17559
18087
  }),
17560
18088
  results: searchResults._rawResults
17561
- }, recommendResults && {
18089
+ }, searchResults.feeds && searchResults.feeds.length > 0 && {
18090
+ compositionFeedsResults: searchResults.feeds.map(function(feed) {
18091
+ return _object_spread_props(_object_spread({}, feed._rawResults[0]), {
18092
+ feedID: feed.feedID
18093
+ });
18094
+ })
18095
+ }), recommendResults && {
17562
18096
  recommendResults: {
17563
18097
  // We have to stringify + parse because of some explicitly undefined values.
17564
18098
  params: JSON.parse(JSON.stringify(recommendResults._state.params)),
@@ -17602,12 +18136,9 @@
17602
18136
  notifyServer: createNotifyServer()
17603
18137
  }).then(function(serverState) {
17604
18138
  var shouldRefetch = false;
17605
- // <DynamicWidgets> requires another query to retrieve the dynamic widgets
17606
- // to render.
18139
+ // Two-pass widgets require another query to discover and mount child widgets.
17607
18140
  walkIndex(searchRef.current.mainIndex, function(index) {
17608
- shouldRefetch = shouldRefetch || index.getWidgets().some(function(widget) {
17609
- return widget.$$type === 'ais.dynamicWidgets';
17610
- });
18141
+ shouldRefetch = shouldRefetch || index.getWidgets().some(isTwoPassWidget);
17611
18142
  });
17612
18143
  if (shouldRefetch) {
17613
18144
  resetWidgetId();
@@ -17656,6 +18187,7 @@
17656
18187
 
17657
18188
  exports.Configure = Configure;
17658
18189
  exports.DynamicWidgets = DynamicWidgets;
18190
+ exports.Feeds = Feeds;
17659
18191
  exports.Index = Index;
17660
18192
  exports.InstantSearch = InstantSearch;
17661
18193
  exports.InstantSearchRSCContext = InstantSearchRSCContext;
@@ -17671,6 +18203,7 @@
17671
18203
  exports.useConnector = useConnector;
17672
18204
  exports.useCurrentRefinements = useCurrentRefinements;
17673
18205
  exports.useDynamicWidgets = useDynamicWidgets;
18206
+ exports.useFeeds = useFeeds;
17674
18207
  exports.useFilterSuggestions = useFilterSuggestions;
17675
18208
  exports.useFrequentlyBoughtTogether = useFrequentlyBoughtTogether;
17676
18209
  exports.useGeoSearch = useGeoSearch;