react-instantsearch-core 7.41.0 → 7.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- /*! React InstantSearch Core 7.41.0 | © Algolia, Inc. and contributors; MIT License | https://github.com/algolia/instantsearch */
1
+ /*! React InstantSearch Core 7.42.0 | © Algolia, Inc. and contributors; MIT License | https://github.com/algolia/instantsearch */
2
2
  (function (global, factory) {
3
3
  typeof exports === 'object' && typeof module !== 'undefined' ? 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.41.0';
27
+ var version$2 = '7.42.0';
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.29.2';
3922
+ version$1 = '3.29.3';
3923
3923
  return version$1;
3924
3924
  }
3925
3925
 
@@ -5980,7 +5980,7 @@
5980
5980
  }
5981
5981
  }
5982
5982
 
5983
- var withUsage$v = createDocumentationMessageGenerator({
5983
+ var withUsage$x = createDocumentationMessageGenerator({
5984
5984
  name: 'configure',
5985
5985
  connector: true
5986
5986
  });
@@ -5996,7 +5996,7 @@
5996
5996
  var renderFn = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : noop, unmountFn = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : noop;
5997
5997
  return function(widgetParams) {
5998
5998
  if (!widgetParams || !isPlainObject(widgetParams.searchParameters)) {
5999
- throw new Error(withUsage$v('The `searchParameters` option expects an object.'));
5999
+ throw new Error(withUsage$x('The `searchParameters` option expects an object.'));
6000
6000
  }
6001
6001
  var connectorState = {};
6002
6002
  function refine(helper) {
@@ -6280,6 +6280,38 @@
6280
6280
  return stableValue;
6281
6281
  }
6282
6282
 
6283
+ /**
6284
+ * Forwards the insights-related search parameters to every Recommend query.
6285
+ *
6286
+ * The insights middleware writes `userToken` and `clickAnalytics` on the main
6287
+ * helper's search state, which only feeds search queries: Recommend queries are
6288
+ * built from their own parameters and never read the search state. Without this,
6289
+ * recommendations can't be personalized, and their responses carry no `queryID`
6290
+ * for the connectors to attribute click and conversion events with.
6291
+ *
6292
+ * Parameters set on a widget win, so an explicit `queryParameters.userToken`
6293
+ * keeps overriding the middleware.
6294
+ */ function addInsightsToRecommendParameters(recommendParameters, param) {
6295
+ var userToken = param.userToken, clickAnalytics = param.clickAnalytics;
6296
+ if (userToken === undefined && clickAnalytics === undefined) {
6297
+ return recommendParameters;
6298
+ }
6299
+ return new algoliasearchHelper.RecommendParameters({
6300
+ params: recommendParameters.params.map(function(params) {
6301
+ // v4 `TrendingFacetsQuery` doesn't include `queryParameters`, but the v5
6302
+ // API and the helper support them, like `connectTrendingFacets` does.
6303
+ var queryParameters = params.queryParameters;
6304
+ return _object_spread_props(_object_spread({}, params), {
6305
+ queryParameters: _object_spread({}, clickAnalytics === undefined ? {} : {
6306
+ clickAnalytics: clickAnalytics
6307
+ }, userToken === undefined ? {} : {
6308
+ userToken: userToken
6309
+ }, queryParameters)
6310
+ });
6311
+ })
6312
+ });
6313
+ }
6314
+
6283
6315
  var id = 0;
6284
6316
  function addWidgetId(widget) {
6285
6317
  if (widget.dependsOn !== 'recommend') {
@@ -7788,13 +7820,13 @@
7788
7820
  return null;
7789
7821
  }
7790
7822
 
7791
- var withUsage$u = createDocumentationMessageGenerator({
7823
+ var withUsage$w = createDocumentationMessageGenerator({
7792
7824
  name: 'dynamic-widgets',
7793
7825
  connector: true
7794
7826
  });
7795
7827
  var connectDynamicWidgets = function connectDynamicWidgets(renderFn) {
7796
7828
  var unmountFn = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : noop;
7797
- checkRendering(renderFn, withUsage$u());
7829
+ checkRendering(renderFn, withUsage$w());
7798
7830
  return function(widgetParams) {
7799
7831
  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 ? [
7800
7832
  '*'
@@ -7804,10 +7836,10 @@
7804
7836
  if (!(widgets && Array.isArray(widgets) && widgets.every(function(widget) {
7805
7837
  return (typeof widget === "undefined" ? "undefined" : _type_of(widget)) === 'object';
7806
7838
  }))) {
7807
- throw new Error(withUsage$u('The `widgets` option expects an array of widgets.'));
7839
+ throw new Error(withUsage$w('The `widgets` option expects an array of widgets.'));
7808
7840
  }
7809
7841
  if (!Array.isArray(facets)) {
7810
- throw new Error(withUsage$u("The `facets` option only accepts an array of facets, you passed ".concat(JSON.stringify(facets))));
7842
+ throw new Error(withUsage$w("The `facets` option only accepts an array of facets, you passed ".concat(JSON.stringify(facets))));
7811
7843
  }
7812
7844
  var localWidgets = new Map();
7813
7845
  return {
@@ -7909,7 +7941,7 @@
7909
7941
  results: results
7910
7942
  });
7911
7943
  if (!Array.isArray(attributesToRender)) {
7912
- throw new Error(withUsage$u('The `transformItems` option expects a function that returns an Array.'));
7944
+ throw new Error(withUsage$w('The `transformItems` option expects a function that returns an Array.'));
7913
7945
  }
7914
7946
  return {
7915
7947
  attributesToRender: attributesToRender,
@@ -8231,19 +8263,19 @@
8231
8263
  return toFeedSearchResults(lastResults._state, raw);
8232
8264
  });
8233
8265
  }
8234
- var withUsage$t = createDocumentationMessageGenerator({
8266
+ var withUsage$v = createDocumentationMessageGenerator({
8235
8267
  name: 'feeds',
8236
8268
  connector: true
8237
8269
  });
8238
8270
  var connectFeeds = function connectFeeds(renderFn) {
8239
8271
  var unmountFn = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : noop;
8240
- checkRendering(renderFn, withUsage$t());
8272
+ checkRendering(renderFn, withUsage$v());
8241
8273
  return function(widgetParams) {
8242
8274
  var isolated = widgetParams.isolated, _widgetParams_transformFeeds = widgetParams.transformFeeds, transformFeeds = _widgetParams_transformFeeds === void 0 ? function(feeds) {
8243
8275
  return feeds;
8244
8276
  } : _widgetParams_transformFeeds;
8245
8277
  if (isolated !== false) {
8246
- throw new Error(withUsage$t('The `isolated` option currently only supports `false`.'));
8278
+ throw new Error(withUsage$v('The `isolated` option currently only supports `false`.'));
8247
8279
  }
8248
8280
  return {
8249
8281
  $$type: 'ais.feeds',
@@ -8251,7 +8283,7 @@
8251
8283
  init: function init(initOptions) {
8252
8284
  var instantSearchInstance = initOptions.instantSearchInstance;
8253
8285
  if (!instantSearchInstance.compositionID) {
8254
- throw new Error(withUsage$t('The `feeds` widget requires a composition-based InstantSearch instance (compositionID must be set).'));
8286
+ throw new Error(withUsage$v('The `feeds` widget requires a composition-based InstantSearch instance (compositionID must be set).'));
8255
8287
  }
8256
8288
  hydrateFeedsFromInitialResultsIfNeeded(instantSearchInstance, initOptions.parent);
8257
8289
  renderFn(_object_spread_props(_object_spread({}, this.getWidgetRenderState(initOptions)), {
@@ -8297,12 +8329,12 @@
8297
8329
  ];
8298
8330
  feedIDs = transformFeeds(feedIDs);
8299
8331
  if (!Array.isArray(feedIDs)) {
8300
- throw new Error(withUsage$t('The `transformFeeds` option expects a function that returns an Array.'));
8332
+ throw new Error(withUsage$v('The `transformFeeds` option expects a function that returns an Array.'));
8301
8333
  }
8302
8334
  if (!feedIDs.every(function(feedID) {
8303
8335
  return typeof feedID === 'string';
8304
8336
  })) {
8305
- throw new Error(withUsage$t('The `transformFeeds` option expects a function that returns an array of feed IDs (strings).'));
8337
+ throw new Error(withUsage$v('The `transformFeeds` option expects a function that returns an array of feed IDs (strings).'));
8306
8338
  }
8307
8339
  return {
8308
8340
  feedIDs: feedIDs,
@@ -8413,7 +8445,7 @@
8413
8445
  }));
8414
8446
  }
8415
8447
 
8416
- var withUsage$s = createDocumentationMessageGenerator({
8448
+ var withUsage$u = createDocumentationMessageGenerator({
8417
8449
  name: 'index-widget'
8418
8450
  });
8419
8451
  /**
@@ -8541,7 +8573,7 @@
8541
8573
  var index = function index(widgetParams) {
8542
8574
  var _widgetParams_EXPERIMENTAL_isolated;
8543
8575
  if (widgetParams === undefined || widgetParams.indexName === undefined && !widgetParams.isolated && !widgetParams.EXPERIMENTAL_isolated) {
8544
- throw new Error(withUsage$s('The `indexName` option is required.'));
8576
+ throw new Error(withUsage$u('The `indexName` option is required.'));
8545
8577
  }
8546
8578
  // When isolated=true, we use an empty string as the default indexName.
8547
8579
  // This is intentional: isolated indices do not require a real index name.
@@ -8634,7 +8666,7 @@
8634
8666
  addWidgets: function addWidgets(widgets) {
8635
8667
  var _this = this;
8636
8668
  if (!Array.isArray(widgets)) {
8637
- throw new Error(withUsage$s('The `addWidgets` method expects an array of widgets.'));
8669
+ throw new Error(withUsage$u('The `addWidgets` method expects an array of widgets.'));
8638
8670
  }
8639
8671
  var flatWidgets = widgets.reduce(function(acc, w) {
8640
8672
  return acc.concat(Array.isArray(w) ? w : [
@@ -8644,7 +8676,7 @@
8644
8676
  if (flatWidgets.some(function(widget) {
8645
8677
  return typeof widget.init !== 'function' && typeof widget.render !== 'function';
8646
8678
  })) {
8647
- throw new Error(withUsage$s('The widget definition expects a `render` and/or an `init` method.'));
8679
+ throw new Error(withUsage$u('The widget definition expects a `render` and/or an `init` method.'));
8648
8680
  }
8649
8681
  flatWidgets.forEach(function(widget) {
8650
8682
  widget.parent = _this;
@@ -8695,7 +8727,7 @@
8695
8727
  removeWidgets: function removeWidgets(widgets) {
8696
8728
  var _this = this;
8697
8729
  if (!Array.isArray(widgets)) {
8698
- throw new Error(withUsage$s('The `removeWidgets` method expects an array of widgets.'));
8730
+ throw new Error(withUsage$u('The `removeWidgets` method expects an array of widgets.'));
8699
8731
  }
8700
8732
  var flatWidgets = widgets.reduce(function(acc, w) {
8701
8733
  return acc.concat(Array.isArray(w) ? w : [
@@ -8705,7 +8737,7 @@
8705
8737
  if (flatWidgets.some(function(widget) {
8706
8738
  return typeof widget.dispose !== 'function';
8707
8739
  })) {
8708
- throw new Error(withUsage$s('The widget definition expects a `dispose` method.'));
8740
+ throw new Error(withUsage$u('The widget definition expects a `dispose` method.'));
8709
8741
  }
8710
8742
  localWidgets = localWidgets.filter(function(widget) {
8711
8743
  return flatWidgets.indexOf(widget) === -1;
@@ -8833,7 +8865,7 @@
8833
8865
  mainHelper.state
8834
8866
  ].concat(_to_consumable_array(resolveSearchParameters(_this))));
8835
8867
  }, function() {
8836
- return _this.getHelper().recommendState;
8868
+ return addInsightsToRecommendParameters(_this.getHelper().recommendState, mainHelper.state);
8837
8869
  });
8838
8870
  var indexInitialResults = (_instantSearchInstance__initialResults = instantSearchInstance._initialResults) === null || _instantSearchInstance__initialResults === void 0 ? void 0 : _instantSearchInstance__initialResults[this.getIndexId()];
8839
8871
  if (indexInitialResults === null || indexInitialResults === void 0 ? void 0 : indexInitialResults.results) {
@@ -9210,7 +9242,7 @@
9210
9242
  });
9211
9243
  }
9212
9244
 
9213
- var version = '4.108.0';
9245
+ var version = '4.109.0';
9214
9246
 
9215
9247
  var ANONYMOUS_TOKEN_COOKIE_KEY = '_ALGOLIA';
9216
9248
  function getCookie(name) {
@@ -9440,7 +9472,8 @@
9440
9472
  helper.overrideStateWithoutTriggeringChangeEvent(_object_spread_props(_object_spread({}, helper.state), {
9441
9473
  userToken: normalizedUserToken
9442
9474
  }));
9443
- if (existingToken && existingToken !== userToken) {
9475
+ if (existingToken && existingToken !== normalizedUserToken) {
9476
+ helper._recommendCache = {};
9444
9477
  instantSearchInstance.scheduleSearch();
9445
9478
  }
9446
9479
  }
@@ -9529,14 +9562,17 @@
9529
9562
  } else if (event.insightsMethod) {
9530
9563
  if (event.insightsMethod === 'viewedObjectIDs') {
9531
9564
  var payload = event.payload;
9565
+ var getViewEventKey = function getViewEventKey(objectID) {
9566
+ return payload.queryID ? "".concat(payload.queryID, ":").concat(objectID) : objectID;
9567
+ };
9532
9568
  var difference = payload.objectIDs.filter(function(objectID) {
9533
- return !viewedObjectIDs.has(objectID);
9569
+ return !viewedObjectIDs.has(getViewEventKey(objectID));
9534
9570
  });
9535
9571
  if (difference.length === 0) {
9536
9572
  return;
9537
9573
  }
9538
9574
  difference.forEach(function(objectID) {
9539
- return viewedObjectIDs.add(objectID);
9575
+ return viewedObjectIDs.add(getViewEventKey(objectID));
9540
9576
  });
9541
9577
  payload.objectIDs = difference;
9542
9578
  }
@@ -9644,10 +9680,10 @@
9644
9680
  * and the ability to set credentials via extra parameters when sending events.
9645
9681
  */ function isModernInsightsClient(client) {
9646
9682
  var _split_map = _sliced_to_array((client.version || '').split('.').map(Number), 2), major = _split_map[0], minor = _split_map[1];
9647
- /* eslint-disable instantsearch/naming-convention */ var v3 = major >= 3;
9683
+ /* oxlint-disable instantsearch/naming-convention */ var v3 = major >= 3;
9648
9684
  var v2_6 = major === 2 && minor >= 6;
9649
9685
  var v1_10 = major === 1 && minor >= 10;
9650
- /* eslint-enable instantsearch/naming-convention */ return v3 || v2_6 || v1_10;
9686
+ /* oxlint-enable instantsearch/naming-convention */ return v3 || v2_6 || v1_10;
9651
9687
  }
9652
9688
  /**
9653
9689
  * While `search-insights` supports both string and number user tokens,
@@ -11068,7 +11104,7 @@
11068
11104
  };
11069
11105
  }
11070
11106
 
11071
- var withUsage$r = createDocumentationMessageGenerator({
11107
+ var withUsage$t = createDocumentationMessageGenerator({
11072
11108
  name: 'instantsearch'
11073
11109
  });
11074
11110
  function defaultCreateURL() {
@@ -11131,7 +11167,7 @@
11131
11167
  _this.setMaxListeners(100);
11132
11168
  var _options_indexName = options.indexName, indexName = _options_indexName === void 0 ? '' : _options_indexName, compositionID = options.compositionID, numberLocale = options.numberLocale, _options_initialUiState = options.initialUiState, initialUiState = _options_initialUiState === void 0 ? {} : _options_initialUiState, _options_routing = options.routing, routing = _options_routing === void 0 ? null : _options_routing, _options_insights = options.insights, insights = _options_insights === void 0 ? undefined : _options_insights, searchFunction = options.searchFunction, _options_stalledSearchDelay = options.stalledSearchDelay, stalledSearchDelay = _options_stalledSearchDelay === void 0 ? 200 : _options_stalledSearchDelay, _options_searchClient = options.searchClient, searchClient = _options_searchClient === void 0 ? null : _options_searchClient, _options_insightsClient = options.insightsClient, insightsClient = _options_insightsClient === void 0 ? null : _options_insightsClient, _options_onStateChange = options.onStateChange, onStateChange = _options_onStateChange === void 0 ? null : _options_onStateChange, _options_future1 = options.future, future = _options_future1 === void 0 ? _object_spread({}, INSTANTSEARCH_FUTURE_DEFAULTS, options.future || {}) : _options_future1;
11133
11169
  if (searchClient === null) {
11134
- throw new Error(withUsage$r('The `searchClient` option is required.'));
11170
+ throw new Error(withUsage$t('The `searchClient` option is required.'));
11135
11171
  }
11136
11172
  if (typeof searchClient.search !== 'function') {
11137
11173
  throw new Error("The `searchClient` must implement a `search` method.\n\nSee: https://www.algolia.com/doc/guides/building-search-ui/going-further/backend-search/in-depth/backend-instantsearch/js/");
@@ -11140,7 +11176,7 @@
11140
11176
  searchClient.addAlgoliaAgent("instantsearch.js (".concat(version, ")"));
11141
11177
  }
11142
11178
  if (insightsClient && typeof insightsClient !== 'function') {
11143
- throw new Error(withUsage$r('The `insightsClient` option should be a function.'));
11179
+ throw new Error(withUsage$t('The `insightsClient` option should be a function.'));
11144
11180
  }
11145
11181
  _this._initialOptions = options;
11146
11182
  _this.client = searchClient;
@@ -11289,12 +11325,12 @@
11289
11325
  * @param widgets The array of widgets to add to InstantSearch.
11290
11326
  */ function addWidgets(widgets) {
11291
11327
  if (!Array.isArray(widgets)) {
11292
- throw new Error(withUsage$r('The `addWidgets` method expects an array of widgets. Please use `addWidget`.'));
11328
+ throw new Error(withUsage$t('The `addWidgets` method expects an array of widgets. Please use `addWidget`.'));
11293
11329
  }
11294
11330
  if (this.compositionID && widgets.some(function(w) {
11295
11331
  return !Array.isArray(w) && isIndexWidget(w) && !w._isolated;
11296
11332
  })) {
11297
- throw new Error(withUsage$r('The `index` widget cannot be used with a composition-based InstantSearch implementation.'));
11333
+ throw new Error(withUsage$t('The `index` widget cannot be used with a composition-based InstantSearch implementation.'));
11298
11334
  }
11299
11335
  this.mainIndex.addWidgets(widgets);
11300
11336
  return this;
@@ -11323,7 +11359,7 @@
11323
11359
  * The widgets must implement a `dispose()` method to clear their states.
11324
11360
  */ function removeWidgets(widgets) {
11325
11361
  if (!Array.isArray(widgets)) {
11326
- throw new Error(withUsage$r('The `removeWidgets` method expects an array of widgets. Please use `removeWidget`.'));
11362
+ throw new Error(withUsage$t('The `removeWidgets` method expects an array of widgets. Please use `removeWidget`.'));
11327
11363
  }
11328
11364
  this.mainIndex.removeWidgets(widgets);
11329
11365
  return this;
@@ -11337,7 +11373,7 @@
11337
11373
  */ function start() {
11338
11374
  var _this = this;
11339
11375
  if (this.started) {
11340
- throw new Error(withUsage$r('The `start` method has already been called once.'));
11376
+ throw new Error(withUsage$t('The `start` method has already been called once.'));
11341
11377
  }
11342
11378
  // This Helper is used for the queries, we don't care about its state. The
11343
11379
  // states are managed at the `index` level. We use this Helper to create
@@ -11545,7 +11581,7 @@
11545
11581
  var _this = this;
11546
11582
  var callOnStateChange = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
11547
11583
  if (!this.mainHelper) {
11548
- throw new Error(withUsage$r('The `start` method needs to be called before `setUiState`.'));
11584
+ throw new Error(withUsage$t('The `start` method needs to be called before `setUiState`.'));
11549
11585
  }
11550
11586
  // We refresh the index UI state to update the local UI state that the
11551
11587
  // main index passes to the function form of `setUiState`.
@@ -11582,7 +11618,7 @@
11582
11618
  value: function createURL() {
11583
11619
  var nextState = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
11584
11620
  if (!this.started) {
11585
- throw new Error(withUsage$r('The `start` method needs to be called before `createURL`.'));
11621
+ throw new Error(withUsage$t('The `start` method needs to be called before `createURL`.'));
11586
11622
  }
11587
11623
  return this._createURL(nextState);
11588
11624
  }
@@ -11591,7 +11627,7 @@
11591
11627
  key: "refresh",
11592
11628
  value: function refresh() {
11593
11629
  if (!this.mainHelper) {
11594
- throw new Error(withUsage$r('The `start` method needs to be called before `refresh`.'));
11630
+ throw new Error(withUsage$t('The `start` method needs to be called before `refresh`.'));
11595
11631
  }
11596
11632
  this.mainHelper.clearCache().search();
11597
11633
  }
@@ -12117,13 +12153,13 @@
12117
12153
  }, children);
12118
12154
  }
12119
12155
 
12120
- var withUsage$q = createDocumentationMessageGenerator({
12156
+ var withUsage$s = createDocumentationMessageGenerator({
12121
12157
  name: 'autocomplete',
12122
12158
  connector: true
12123
12159
  });
12124
12160
  var connectAutocomplete = function connectAutocomplete(renderFn) {
12125
12161
  var unmountFn = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : noop;
12126
- checkRendering(renderFn, withUsage$q());
12162
+ checkRendering(renderFn, withUsage$s());
12127
12163
  return function(widgetParams) {
12128
12164
  var _ref = widgetParams || {}, _ref_escapeHTML = _ref.escapeHTML, escapeHTML = _ref_escapeHTML === void 0 ? true : _ref_escapeHTML, _ref_transformItems = _ref.transformItems, transformItems = _ref_transformItems === void 0 ? function(indices) {
12129
12165
  return indices;
@@ -12236,20 +12272,20 @@
12236
12272
  return useConnector(connectAutocomplete, props, additionalWidgetProperties);
12237
12273
  }
12238
12274
 
12239
- var withUsage$p = createDocumentationMessageGenerator({
12275
+ var withUsage$r = createDocumentationMessageGenerator({
12240
12276
  name: 'breadcrumb',
12241
12277
  connector: true
12242
12278
  });
12243
12279
  var connectBreadcrumb = function connectBreadcrumb(renderFn) {
12244
12280
  var unmountFn = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : noop;
12245
- checkRendering(renderFn, withUsage$p());
12281
+ checkRendering(renderFn, withUsage$r());
12246
12282
  var connectorState = {};
12247
12283
  return function(widgetParams) {
12248
12284
  var _ref = widgetParams || {}, attributes = _ref.attributes, _ref_separator = _ref.separator, separator = _ref_separator === void 0 ? ' > ' : _ref_separator, _ref_rootPath = _ref.rootPath, rootPath = _ref_rootPath === void 0 ? null : _ref_rootPath, _ref_transformItems = _ref.transformItems, transformItems = _ref_transformItems === void 0 ? function(items) {
12249
12285
  return items;
12250
12286
  } : _ref_transformItems;
12251
12287
  if (!attributes || !Array.isArray(attributes) || attributes.length === 0) {
12252
- throw new Error(withUsage$p('The `attributes` option expects an array of strings.'));
12288
+ throw new Error(withUsage$r('The `attributes` option expects an array of strings.'));
12253
12289
  }
12254
12290
  var _attributes = _sliced_to_array(attributes, 1), hierarchicalFacetName = _attributes[0];
12255
12291
  function getRefinedState(state, facetValue) {
@@ -12395,6 +12431,76 @@
12395
12431
  return useConnector(connectBreadcrumb, props, additionalWidgetProperties);
12396
12432
  }
12397
12433
 
12434
+ var tryParseJson = function tryParseJson(value) {
12435
+ try {
12436
+ return JSON.parse(value);
12437
+ } catch (unused) {
12438
+ return undefined;
12439
+ }
12440
+ };
12441
+ var repairPartialJson = function repairPartialJson(value) {
12442
+ var repaired = value.trim();
12443
+ if (!repaired) {
12444
+ return repaired;
12445
+ }
12446
+ var inString = false;
12447
+ var isEscaped = false;
12448
+ var stack = [];
12449
+ for(var index = 0; index < repaired.length; index++){
12450
+ var char = repaired[index];
12451
+ if (inString) {
12452
+ if (isEscaped) {
12453
+ isEscaped = false;
12454
+ } else if (char === '\\') {
12455
+ isEscaped = true;
12456
+ } else if (char === '"') {
12457
+ inString = false;
12458
+ }
12459
+ continue;
12460
+ }
12461
+ if (char === '"') {
12462
+ inString = true;
12463
+ continue;
12464
+ }
12465
+ if (char === '{' || char === '[') {
12466
+ stack.push(char);
12467
+ continue;
12468
+ }
12469
+ if (char === '}' && stack[stack.length - 1] === '{') {
12470
+ stack.pop();
12471
+ continue;
12472
+ }
12473
+ if (char === ']' && stack[stack.length - 1] === '[') {
12474
+ stack.pop();
12475
+ }
12476
+ }
12477
+ if (inString && !isEscaped) {
12478
+ repaired += '"';
12479
+ }
12480
+ repaired = repaired.replace(RegExp(",\\s*$", "u"), '');
12481
+ if (stack.length > 0) {
12482
+ repaired += stack.reverse().map(function(opening) {
12483
+ return opening === '{' ? '}' : ']';
12484
+ }).join('');
12485
+ }
12486
+ return repaired.replace(RegExp(",\\s*([}\\]])", "gu"), '$1');
12487
+ };
12488
+ var parsePartialJson = function parsePartialJson(accumulatedRawJson, fallbackValue) {
12489
+ var normalized = accumulatedRawJson.trim();
12490
+ if (!normalized) {
12491
+ return fallbackValue;
12492
+ }
12493
+ var directParsed = tryParseJson(normalized);
12494
+ if (directParsed !== undefined) {
12495
+ return directParsed;
12496
+ }
12497
+ var repairedParsed = tryParseJson(repairPartialJson(normalized));
12498
+ if (repairedParsed !== undefined) {
12499
+ return repairedParsed;
12500
+ }
12501
+ return fallbackValue;
12502
+ };
12503
+
12398
12504
  /**
12399
12505
  * Stream parser for parsing SSE (Server-Sent Events) streams.
12400
12506
  * The AI SDK 5 format uses SSE with JSON payloads prefixed by "data: ".
@@ -12676,75 +12782,6 @@
12676
12782
  }
12677
12783
 
12678
12784
  var _computedKey$1;
12679
- var tryParseJson = function tryParseJson(value) {
12680
- try {
12681
- return JSON.parse(value);
12682
- } catch (unused) {
12683
- return undefined;
12684
- }
12685
- };
12686
- var repairPartialJson = function repairPartialJson(value) {
12687
- var repaired = value.trim();
12688
- if (!repaired) {
12689
- return repaired;
12690
- }
12691
- var inString = false;
12692
- var isEscaped = false;
12693
- var stack = [];
12694
- for(var index = 0; index < repaired.length; index++){
12695
- var char = repaired[index];
12696
- if (inString) {
12697
- if (isEscaped) {
12698
- isEscaped = false;
12699
- } else if (char === '\\') {
12700
- isEscaped = true;
12701
- } else if (char === '"') {
12702
- inString = false;
12703
- }
12704
- continue;
12705
- }
12706
- if (char === '"') {
12707
- inString = true;
12708
- continue;
12709
- }
12710
- if (char === '{' || char === '[') {
12711
- stack.push(char);
12712
- continue;
12713
- }
12714
- if (char === '}' && stack[stack.length - 1] === '{') {
12715
- stack.pop();
12716
- continue;
12717
- }
12718
- if (char === ']' && stack[stack.length - 1] === '[') {
12719
- stack.pop();
12720
- }
12721
- }
12722
- if (inString && !isEscaped) {
12723
- repaired += '"';
12724
- }
12725
- repaired = repaired.replace(RegExp(",\\s*$", "u"), '');
12726
- if (stack.length > 0) {
12727
- repaired += stack.reverse().map(function(opening) {
12728
- return opening === '{' ? '}' : ']';
12729
- }).join('');
12730
- }
12731
- return repaired.replace(RegExp(",\\s*([}\\]])", "gu"), '$1');
12732
- };
12733
- var parseToolInputDelta = function parseToolInputDelta(accumulatedRawInput, fallbackInput) {
12734
- var normalized = accumulatedRawInput.trim();
12735
- if (!normalized) {
12736
- return fallbackInput;
12737
- }
12738
- var directParsed = tryParseJson(normalized);
12739
- if (directParsed !== undefined) {
12740
- return directParsed;
12741
- }
12742
- var repairedParsed = tryParseJson(repairPartialJson(normalized));
12743
- if (repairedParsed !== undefined) {
12744
- return repairedParsed;
12745
- }
12746
- return fallbackInput;
12747
- };
12748
12785
  var defaultGuardrailFallbackResponse = 'Sorry, we are not able to generate a response at the moment.';
12749
12786
  _computedKey$1 = /** @internal */ '~addToolResultForMessage';
12750
12787
  var _computedKey1$1 = _computedKey$1;
@@ -13578,7 +13615,7 @@
13578
13615
  toolRawInputByCallId[chunk.toolCallId] = nextRawInput;
13579
13616
  var toolName = (_chunk_toolName = chunk.toolName) !== null && _chunk_toolName !== void 0 ? _chunk_toolName : existingPart === null || existingPart === void 0 ? void 0 : (_existingPart_type = existingPart.type) === null || _existingPart_type === void 0 ? void 0 : _existingPart_type.replace('tool-', '');
13580
13617
  var shouldRepair = toolName ? (_ref2 = (_this_shouldRepairToolInput = (_this1 = _this).shouldRepairToolInput) === null || _this_shouldRepairToolInput === void 0 ? void 0 : _this_shouldRepairToolInput.call(_this1, toolName)) !== null && _ref2 !== void 0 ? _ref2 : true : true;
13581
- var parsedInput = shouldRepair ? parseToolInputDelta(nextRawInput, existingPart === null || existingPart === void 0 ? void 0 : existingPart.input) : existingPart === null || existingPart === void 0 ? void 0 : existingPart.input;
13618
+ var parsedInput = shouldRepair ? parsePartialJson(nextRawInput, existingPart === null || existingPart === void 0 ? void 0 : existingPart.input) : existingPart === null || existingPart === void 0 ? void 0 : existingPart.input;
13582
13619
  var nextToolPart = _object_spread_props(_object_spread({}, existingPart !== null && existingPart !== void 0 ? existingPart : {
13583
13620
  type: "tool-".concat(chunk.toolName),
13584
13621
  toolCallId: chunk.toolCallId
@@ -13681,7 +13718,7 @@
13681
13718
  var previousRawOutput = (_ref3 = (_ref4 = existingPart2 === null || existingPart2 === void 0 ? void 0 : existingPart2.rawOutput) !== null && _ref4 !== void 0 ? _ref4 : toolRawOutputByCallId[toolCallId]) !== null && _ref3 !== void 0 ? _ref3 : '';
13682
13719
  var nextRawOutput = "".concat(previousRawOutput).concat(delta);
13683
13720
  toolRawOutputByCallId[toolCallId] = nextRawOutput;
13684
- var parsedOutput = parseToolInputDelta(nextRawOutput, existingPart2 === null || existingPart2 === void 0 ? void 0 : existingPart2.output);
13721
+ var parsedOutput = parsePartialJson(nextRawOutput, existingPart2 === null || existingPart2 === void 0 ? void 0 : existingPart2.output);
13685
13722
  var nextToolPart1 = _object_spread_props(_object_spread({}, existingPart2 !== null && existingPart2 !== void 0 ? existingPart2 : {
13686
13723
  type: "tool-".concat(toolName1),
13687
13724
  toolCallId: toolCallId,
@@ -13971,9 +14008,25 @@
13971
14008
 
13972
14009
  var _computedKey, _computedKey1, _computedKey2, _computedKey3, _computedKey4, _computedKey5;
13973
14010
  var CACHE_KEY = 'instantsearch-chat-initial-messages';
14011
+ // Message history is a browser concern, and a server render constructs a Chat
14012
+ // too. Reading storage there throws during rendering; the write below only
14013
+ // throws into its own `catch`, so gating it just stops a pointless attempt.
13974
14014
  function getDefaultInitialMessages(id) {
13975
- var initialMessages = sessionStorage.getItem(CACHE_KEY + (id ? "-".concat(id) : ''));
13976
- return initialMessages ? JSON.parse(initialMessages) : [];
14015
+ return safelyRunOnBrowser(function() {
14016
+ try {
14017
+ // `sessionStorage` is not available in every environment with a
14018
+ // `window` (e.g. React Native), and some browsers throw on access
14019
+ // when storage is disabled.
14020
+ var initialMessages = sessionStorage.getItem(CACHE_KEY + (id ? "-".concat(id) : ''));
14021
+ return initialMessages ? JSON.parse(initialMessages) : [];
14022
+ } catch (e) {
14023
+ return [];
14024
+ }
14025
+ }, {
14026
+ fallback: function fallback() {
14027
+ return [];
14028
+ }
14029
+ });
13977
14030
  }
13978
14031
  _computedKey = '~registerMessagesCallback', _computedKey1 = '~registerStatusCallback', _computedKey2 = '~registerErrorCallback';
13979
14032
  var _computedKey6 = _computedKey, _computedKey7 = _computedKey1, _computedKey8 = _computedKey2;
@@ -14052,11 +14105,13 @@
14052
14105
  }
14053
14106
  var saveMessagesInLocalStorage = function saveMessagesInLocalStorage() {
14054
14107
  if (_this.status === 'ready') {
14055
- try {
14056
- sessionStorage.setItem(CACHE_KEY + (id ? "-".concat(id) : ''), JSON.stringify(_this.messages));
14057
- } catch (e) {
14058
- // Do nothing if sessionStorage is not available or full
14059
- }
14108
+ safelyRunOnBrowser(function() {
14109
+ try {
14110
+ sessionStorage.setItem(CACHE_KEY + (id ? "-".concat(id) : ''), JSON.stringify(_this.messages));
14111
+ } catch (e) {
14112
+ // Do nothing if sessionStorage is not available or full
14113
+ }
14114
+ });
14060
14115
  }
14061
14116
  };
14062
14117
  this['~registerMessagesCallback'](saveMessagesInLocalStorage);
@@ -14132,7 +14187,7 @@
14132
14187
  // it is non-empty and the chat is not already processing a message.
14133
14188
  // Returns true when a message was submitted, so callers can clear their input.
14134
14189
  function openChat(chatRenderState) {
14135
- var _ref = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}, message = _ref.message, referer = _ref.referer;
14190
+ var _ref = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}, message = _ref.message, referer = _ref.referer, turnContext = _ref.turnContext;
14136
14191
  var _ref1;
14137
14192
  var _chatRenderState_setOpen;
14138
14193
  if (!chatRenderState) {
@@ -14148,9 +14203,13 @@
14148
14203
  if (isChatBusy(chatRenderState) || !chatRenderState.sendMessage) {
14149
14204
  return false;
14150
14205
  }
14151
- chatRenderState.sendMessage({
14206
+ chatRenderState.sendMessage(_object_spread({
14152
14207
  text: trimmed
14153
- }, referer ? {
14208
+ }, turnContext ? {
14209
+ metadata: {
14210
+ turnContext: turnContext
14211
+ }
14212
+ } : {}), referer ? {
14154
14213
  headers: {
14155
14214
  'x-algolia-referer': referer
14156
14215
  }
@@ -14359,7 +14418,7 @@
14359
14418
  return DefaultChatTransport;
14360
14419
  }(HttpChatTransport);
14361
14420
 
14362
- var withUsage$o = createDocumentationMessageGenerator({
14421
+ var withUsage$q = createDocumentationMessageGenerator({
14363
14422
  name: 'chat',
14364
14423
  connector: true
14365
14424
  });
@@ -14380,26 +14439,36 @@
14380
14439
  attributesToClear: attributesToClear
14381
14440
  }));
14382
14441
  if (params.facetFilters) {
14383
- var attributes = flat(params.facetFilters).map(function(filter) {
14384
- var _filter_split = _sliced_to_array(filter.split(':'), 2), attribute = _filter_split[0], value = _filter_split[1];
14385
- return {
14386
- attribute: attribute,
14387
- value: value
14388
- };
14389
- });
14390
- attributes.forEach(function(param) {
14442
+ var refinements = flat(params.facetFilters).reduce(function(acc, filter) {
14443
+ var separatorIndex = filter.indexOf(':');
14444
+ if (separatorIndex > 0) {
14445
+ acc.push({
14446
+ attribute: filter.slice(0, separatorIndex),
14447
+ value: filter.slice(separatorIndex + 1)
14448
+ });
14449
+ }
14450
+ return acc;
14451
+ }, []);
14452
+ var hierarchicalRefinements = new Map();
14453
+ refinements.forEach(function(param) {
14391
14454
  var attribute = param.attribute, value = param.value;
14392
- if (!helper.state.isConjunctiveFacet(attribute) && !helper.state.isHierarchicalFacet(attribute) && !helper.state.isDisjunctiveFacet(attribute)) {
14393
- var s = helper.state.addDisjunctiveFacet(attribute);
14394
- helper.setState(s);
14395
- helper.toggleFacetRefinement(attribute, value);
14396
- } else {
14397
- var _helper_state_hierarchicalFacets_find;
14398
- var attr = ((_helper_state_hierarchicalFacets_find = helper.state.hierarchicalFacets.find(function(facet) {
14399
- return facet.name === attribute;
14400
- })) === null || _helper_state_hierarchicalFacets_find === void 0 ? void 0 : _helper_state_hierarchicalFacets_find.name) || attribute;
14401
- helper.toggleFacetRefinement(attr, value);
14455
+ var hierarchicalFacet = helper.state.hierarchicalFacets.find(function(facet) {
14456
+ return facet.name === attribute || facet.attributes.includes(attribute);
14457
+ });
14458
+ if (hierarchicalFacet) {
14459
+ var currentValue = hierarchicalRefinements.get(hierarchicalFacet.name);
14460
+ if (currentValue === undefined || value.length > currentValue.length) {
14461
+ hierarchicalRefinements.set(hierarchicalFacet.name, value);
14462
+ }
14463
+ return;
14402
14464
  }
14465
+ if (!helper.state.isConjunctiveFacet(attribute) && !helper.state.isDisjunctiveFacet(attribute)) {
14466
+ helper.setState(helper.state.addDisjunctiveFacet(attribute));
14467
+ }
14468
+ helper.toggleFacetRefinement(attribute, value);
14469
+ });
14470
+ hierarchicalRefinements.forEach(function(value, name) {
14471
+ helper.toggleFacetRefinement(name, value);
14403
14472
  });
14404
14473
  }
14405
14474
  if (params.query) {
@@ -14410,7 +14479,7 @@
14410
14479
  }
14411
14480
  var connectChat = function connectChat(renderFn) {
14412
14481
  var unmountFn = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : noop;
14413
- checkRendering(renderFn, withUsage$o());
14482
+ checkRendering(renderFn, withUsage$q());
14414
14483
  return function(widgetParams) {
14415
14484
  var _ref = widgetParams || {}, _ref_resume = _ref.resume, resume = _ref_resume === void 0 ? false : _ref_resume, _ref_tools = _ref.tools, tools = _ref_tools === void 0 ? {} : _ref_tools, _ref_type = _ref.type, type = _ref_type === void 0 ? 'chat' : _ref_type, context = _ref.context, initialUserMessage = _ref.initialUserMessage, initialMessages = _ref.initialMessages, _ref_disableTriggerValidation = _ref.disableTriggerValidation, disableTriggerValidation = _ref_disableTriggerValidation === void 0 ? false : _ref_disableTriggerValidation, _ref_sendAutomaticallyWhen = _ref.sendAutomaticallyWhen, sendAutomaticallyWhen = _ref_sendAutomaticallyWhen === void 0 ? lastAssistantMessageIsCompleteWithToolCalls : _ref_sendAutomaticallyWhen, _ref_requiresSearch = _ref.requiresSearch, requiresSearch = _ref_requiresSearch === void 0 ? true : _ref_requiresSearch, options = _object_without_properties(_ref, [
14416
14485
  "resume",
@@ -14488,6 +14557,11 @@
14488
14557
  hasValidatedEntryPoints = true;
14489
14558
  };
14490
14559
  var makeChatInstance = function makeChatInstance(instantSearchInstance) {
14560
+ // A caller supplied `chat` already owns its transport, so it bypasses the
14561
+ // connector's transport construction and validation below.
14562
+ if ('chat' in options) {
14563
+ return options.chat;
14564
+ }
14491
14565
  var transport;
14492
14566
  var client = instantSearchInstance.client;
14493
14567
  var _getAppIdAndApiKey = _sliced_to_array(getAppIdAndApiKey(client), 2), appId = _getAppIdAndApiKey[0], apiKey = _getAppIdAndApiKey[1];
@@ -14537,7 +14611,7 @@
14537
14611
  if ('agentId' in options && options.agentId) {
14538
14612
  var _options_requestOptions, _options_requestOptions1;
14539
14613
  if (!appId || !apiKey) {
14540
- throw new Error(withUsage$o('Could not extract Algolia credentials from the search client.'));
14614
+ throw new Error(withUsage$q('Could not extract Algolia credentials from the search client.'));
14541
14615
  }
14542
14616
  var createApi = function createApi() {
14543
14617
  var bypassCache = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : false;
@@ -14554,7 +14628,7 @@
14554
14628
  var baseApi = createApi();
14555
14629
  transport = new DefaultChatTransport({
14556
14630
  api: baseApi,
14557
- headers: _object_spread_props(_object_spread({}, _instanceof((_options_requestOptions = options.requestOptions) === null || _options_requestOptions === void 0 ? void 0 : _options_requestOptions.headers, Headers) ? Object.fromEntries(options.requestOptions.headers.entries()) : (_options_requestOptions1 = options.requestOptions) === null || _options_requestOptions1 === void 0 ? void 0 : _options_requestOptions1.headers), {
14631
+ headers: _object_spread_props(_object_spread({}, typeof Headers !== 'undefined' && _instanceof((_options_requestOptions = options.requestOptions) === null || _options_requestOptions === void 0 ? void 0 : _options_requestOptions.headers, Headers) ? Object.fromEntries(options.requestOptions.headers.entries()) : (_options_requestOptions1 = options.requestOptions) === null || _options_requestOptions1 === void 0 ? void 0 : _options_requestOptions1.headers), {
14558
14632
  // Preserve the required Algolia identity headers and chat agent
14559
14633
  // marker, even when requestOptions.headers contains the same keys.
14560
14634
  'x-algolia-application-id': appId,
@@ -14576,10 +14650,7 @@
14576
14650
  });
14577
14651
  }
14578
14652
  if (!transport) {
14579
- throw new Error(withUsage$o('You need to provide either an `agentId` or a `transport`.'));
14580
- }
14581
- if ('chat' in options) {
14582
- return options.chat;
14653
+ throw new Error(withUsage$q('You need to provide either an `agentId` or a `transport`.'));
14583
14654
  }
14584
14655
  return new Chat(_object_spread_props(_object_spread({}, options), {
14585
14656
  sendAutomaticallyWhen: sendAutomaticallyWhen,
@@ -14659,7 +14730,7 @@
14659
14730
  if (agentId && feedback) {
14660
14731
  var _getAppIdAndApiKey = _sliced_to_array(getAppIdAndApiKey(initOptions.instantSearchInstance.client), 2), appId = _getAppIdAndApiKey[0], apiKey = _getAppIdAndApiKey[1];
14661
14732
  if (!appId || !apiKey) {
14662
- throw new Error(withUsage$o('Could not extract Algolia credentials from the search client.'));
14733
+ throw new Error(withUsage$q('Could not extract Algolia credentials from the search client.'));
14663
14734
  }
14664
14735
  feedbackAbortController = new AbortController();
14665
14736
  _sendChatMessageFeedback = function _sendChatMessageFeedback(messageId, vote) {
@@ -14680,21 +14751,32 @@
14680
14751
  }
14681
14752
  var hasExistingMessages = _chatInstance.messages.length > 0;
14682
14753
  // Set initialMessages before registering callbacks to avoid
14683
- // triggering re-renders during init
14684
- if ((initialMessages === null || initialMessages === void 0 ? void 0 : initialMessages.length) && !resume && !hasExistingMessages) {
14685
- _chatInstance.messages = initialMessages;
14686
- }
14687
- _chatInstance['~registerErrorCallback'](render);
14688
- _chatInstance['~registerMessagesCallback'](render);
14689
- _chatInstance['~registerStatusCallback'](render);
14690
- if (resume) {
14691
- _chatInstance.resumeStream();
14692
- }
14693
- if (initialUserMessage && !resume && !hasExistingMessages) {
14694
- _chatInstance.sendMessage({
14695
- text: initialUserMessage
14696
- });
14697
- }
14754
+ // triggering re-renders during init. A server render owns no
14755
+ // conversation, so it leaves the instance empty.
14756
+ safelyRunOnBrowser(function() {
14757
+ if ((initialMessages === null || initialMessages === void 0 ? void 0 : initialMessages.length) && !resume && !hasExistingMessages) {
14758
+ _chatInstance.messages = initialMessages;
14759
+ }
14760
+ });
14761
+ safelyRunOnBrowser(function() {
14762
+ _chatInstance['~registerErrorCallback'](render);
14763
+ _chatInstance['~registerMessagesCallback'](render);
14764
+ _chatInstance['~registerStatusCallback'](render);
14765
+ });
14766
+ // Resuming and sending reach the network, which a server render must
14767
+ // not: the HTML pass repeats what `getServerState` already rendered, so
14768
+ // each send happens at least twice, and each failure resolves into chat
14769
+ // state well after the render that started it has finished.
14770
+ safelyRunOnBrowser(function() {
14771
+ if (resume) {
14772
+ _chatInstance.resumeStream();
14773
+ }
14774
+ if (initialUserMessage && !resume && !hasExistingMessages) {
14775
+ _chatInstance.sendMessage({
14776
+ text: initialUserMessage
14777
+ });
14778
+ }
14779
+ });
14698
14780
  renderFn(_object_spread_props(_object_spread({}, this.getWidgetRenderState(initOptions)), {
14699
14781
  instantSearchInstance: instantSearchInstance
14700
14782
  }), true);
@@ -14726,6 +14808,10 @@
14726
14808
  function applyFilters(params) {
14727
14809
  return updateStateFromSearchToolInput(params, helper);
14728
14810
  }
14811
+ var insightsEventContext = {
14812
+ agentId: agentId,
14813
+ instantSearchStatus: instantSearchInstance.status
14814
+ };
14729
14815
  var toolsWithAddToolResult = {};
14730
14816
  Object.entries(tools).forEach(function(param) {
14731
14817
  var _param = _sliced_to_array(param, 2), key = _param[0], tool = _param[1];
@@ -14733,7 +14819,8 @@
14733
14819
  addToolResult: _chatInstance.addToolResult,
14734
14820
  '~addToolResultForMessage': _chatInstance['~addToolResultForMessage'],
14735
14821
  applyFilters: applyFilters,
14736
- sendEvent: sendEvent
14822
+ sendEvent: sendEvent,
14823
+ insightsEventContext: insightsEventContext
14737
14824
  });
14738
14825
  toolsWithAddToolResult[key] = toolWithAddToolResult;
14739
14826
  });
@@ -14802,8 +14889,625 @@
14802
14889
  };
14803
14890
  };
14804
14891
 
14892
+ var subscribe = function subscribe() {
14893
+ return function() {};
14894
+ };
14895
+ var getClientSnapshot = function getClientSnapshot() {
14896
+ return true;
14897
+ };
14898
+ var getServerSnapshot = function getServerSnapshot() {
14899
+ return false;
14900
+ };
14901
+ function useNativeIsHydrated() {
14902
+ return React__namespace.useSyncExternalStore(subscribe, getClientSnapshot, getServerSnapshot);
14903
+ }
14904
+ // React 16 and 17 have no `useSyncExternalStore`, so the flip waits for an
14905
+ // effect and the render itself cannot tell hydration from a plain mount. These
14906
+ // contexts provide that signal for the supported `getServerState` and
14907
+ // `InstantSearchSSRProvider` flow: the server context covers state collection,
14908
+ // and the SSR context covers HTML rendering and hydration.
14909
+ //
14910
+ // This can cost an extra render: a mount inside a provider that carries server
14911
+ // state is withheld once even when there is no server markup to reproduce. A
14912
+ // mount outside both contexts is never withheld.
14913
+ //
14914
+ // The shim's React 16 and 17 fallback ignores the server snapshot, so using it
14915
+ // here would not change this limitation.
14916
+ function useLegacyIsHydrated() {
14917
+ var serverContext = useInstantSearchServerContext();
14918
+ var ssrContext = useInstantSearchSSRContext();
14919
+ var isServerRendered = serverContext !== null || ssrContext !== null;
14920
+ var _React_useState = _sliced_to_array(React__namespace.useState(!isServerRendered), 2), isHydrated = _React_useState[0], setIsHydrated = _React_useState[1];
14921
+ React__namespace.useEffect(function() {
14922
+ setIsHydrated(true);
14923
+ }, []);
14924
+ return isHydrated;
14925
+ }
14926
+ /**
14927
+ * Whether this render can use browser state, or has to reproduce the markup a
14928
+ * server produced without it.
14929
+ *
14930
+ * @internal
14931
+ */ var useIsHydrated = typeof React__namespace.useSyncExternalStore === 'function' ? useNativeIsHydrated : useLegacyIsHydrated;
14932
+
14805
14933
  function useChat(props, additionalWidgetProperties) {
14806
- return useConnector(connectChat, props, additionalWidgetProperties);
14934
+ var isHydrated = useIsHydrated();
14935
+ var chatState = useConnector(connectChat, props, additionalWidgetProperties);
14936
+ if (isHydrated) {
14937
+ return chatState;
14938
+ }
14939
+ // Server rendering only promises the closed Chat shell, so a render that has
14940
+ // to reproduce that markup shows no conversation either. `status` is pinned
14941
+ // with `messages` because it diverges two ways: a server render suppresses
14942
+ // `resumeStream()`, which the browser runs synchronously while initialising,
14943
+ // and a caller-owned chat can already be streaming. `error` is pinned because
14944
+ // a caller-owned chat can already have failed, which a connector-built one
14945
+ // cannot, since its failures arrive in a microtask. `suggestions` is pinned
14946
+ // because the connector derives them from those messages. Only an `id` given
14947
+ // as a connector option passes through, because that value is the same on
14948
+ // both sides. Anything else is withheld: the default is random per Chat, and
14949
+ // an `id` carried by a caller-owned instance is no safer, since the server and
14950
+ // the browser each construct their own.
14951
+ return _object_spread_props(_object_spread({}, chatState), {
14952
+ error: undefined,
14953
+ id: 'id' in props && props.id || '',
14954
+ messages: [],
14955
+ status: 'ready',
14956
+ suggestions: undefined
14957
+ });
14958
+ }
14959
+
14960
+ function buildEndpoint(param) {
14961
+ var appId = param.appId, agentId = param.agentId;
14962
+ return "https://".concat(appId, ".algolia.net/agent-studio/1/agents/").concat(agentId, "/tasks");
14963
+ }
14964
+ function resolveEndpoint(params) {
14965
+ if (params.transport) {
14966
+ return {
14967
+ endpoint: params.transport.api,
14968
+ headers: params.transport.headers || {},
14969
+ prepareSendMessagesRequest: params.transport.prepareSendMessagesRequest
14970
+ };
14971
+ }
14972
+ if (!params.appId || !params.apiKey || !params.agentId) {
14973
+ throw new Error('[tasks] Either `transport` or `{ appId, apiKey, agentId }` is required.');
14974
+ }
14975
+ var headers = {
14976
+ 'x-algolia-application-id': params.appId,
14977
+ 'x-algolia-api-key': params.apiKey
14978
+ };
14979
+ if (params.algoliaAgent) {
14980
+ headers['x-algolia-agent'] = "".concat(params.algoliaAgent, "; tasks");
14981
+ }
14982
+ return {
14983
+ endpoint: buildEndpoint({
14984
+ appId: params.appId,
14985
+ agentId: params.agentId
14986
+ }),
14987
+ headers: headers
14988
+ };
14989
+ }
14990
+
14991
+ function buildTaskPayload(param) {
14992
+ var task = param.task, input = param.input, prepareRequest = param.prepareRequest;
14993
+ var payload = {
14994
+ task: task,
14995
+ input: input
14996
+ };
14997
+ return prepareRequest ? prepareRequest(payload).body : payload;
14998
+ }
14999
+ function withStreamParam(url) {
15000
+ return url.includes('?') ? "".concat(url, "&stream=true") : "".concat(url, "?stream=true");
15001
+ }
15002
+ function resolveStreamedOutput(data, previous) {
15003
+ return typeof data === 'string' ? parsePartialJson(data, previous) : data;
15004
+ }
15005
+ function consumeTaskStream(body, onData) {
15006
+ return new Promise(function(resolve, reject) {
15007
+ var chunkStream = parseJsonEventStream(body);
15008
+ var latest;
15009
+ processStream(chunkStream, function(chunk) {
15010
+ if (!chunk) {
15011
+ return;
15012
+ }
15013
+ // A terminal `error` event aborts the task: reject rather than let the
15014
+ // stream close and resolve the last partial snapshot as a success.
15015
+ // Throwing here lets `processStream` release the reader and stop
15016
+ // consuming; the rejection propagates to the caller's `.catch`.
15017
+ if (chunk.type === 'error') {
15018
+ throw new Error(chunk.errorText || 'Task stream error');
15019
+ }
15020
+ if (chunk.type !== 'data-task-output') {
15021
+ return;
15022
+ }
15023
+ latest = resolveStreamedOutput(chunk.data, latest);
15024
+ if (onData) {
15025
+ onData(latest);
15026
+ }
15027
+ }, function() {
15028
+ return resolve(latest);
15029
+ }, reject);
15030
+ });
15031
+ }
15032
+ function fetchTask(param) {
15033
+ var endpoint = param.endpoint, headers = param.headers, payload = param.payload, onData = param.onData, _param_stream = param.stream, stream = _param_stream === void 0 ? true : _param_stream;
15034
+ return fetch(stream ? withStreamParam(endpoint) : endpoint, {
15035
+ method: 'POST',
15036
+ headers: _object_spread_props(_object_spread({}, headers), {
15037
+ 'Content-Type': 'application/json'
15038
+ }),
15039
+ body: JSON.stringify(payload)
15040
+ }).then(function(response) {
15041
+ var _response_headers_get, _response_headers;
15042
+ if (!response.ok) {
15043
+ throw new Error("HTTP error ".concat(response.status));
15044
+ }
15045
+ var contentType = ((_response_headers = response.headers) === null || _response_headers === void 0 ? void 0 : (_response_headers_get = _response_headers.get) === null || _response_headers_get === void 0 ? void 0 : _response_headers_get.call(_response_headers, 'content-type')) || '';
15046
+ if (stream && response.body && contentType.includes('text/event-stream')) {
15047
+ return consumeTaskStream(response.body, onData);
15048
+ }
15049
+ return response.json();
15050
+ });
15051
+ }
15052
+ function unwrap(envelope) {
15053
+ return envelope === null || envelope === void 0 ? void 0 : envelope.output;
15054
+ }
15055
+ function createTaskRunner(param) {
15056
+ var endpoint = param.endpoint, headers = param.headers, task = param.task, _param_stream = param.stream, stream = _param_stream === void 0 ? true : _param_stream, prepareRequest = param.prepareRequest;
15057
+ return {
15058
+ submit: function submit(variables) {
15059
+ var onData = (arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}).onData;
15060
+ var payload = buildTaskPayload({
15061
+ task: task,
15062
+ input: variables,
15063
+ prepareRequest: prepareRequest
15064
+ });
15065
+ return fetchTask({
15066
+ endpoint: endpoint,
15067
+ headers: headers,
15068
+ payload: payload,
15069
+ stream: stream,
15070
+ onData: onData ? function(partial) {
15071
+ return onData(unwrap(partial));
15072
+ } : undefined
15073
+ }).then(unwrap);
15074
+ }
15075
+ };
15076
+ }
15077
+
15078
+ var withUsage$p = createDocumentationMessageGenerator({
15079
+ name: 'tasks',
15080
+ connector: true
15081
+ });
15082
+ var connectTasks = function connectTasks(renderFn) {
15083
+ var unmountFn = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : noop;
15084
+ checkRendering(renderFn, withUsage$p());
15085
+ return function(widgetParams) {
15086
+ var agentId = widgetParams.agentId, transport = widgetParams.transport, task = widgetParams.task, _widgetParams_stream = widgetParams.stream, stream = _widgetParams_stream === void 0 ? true : _widgetParams_stream;
15087
+ if (!agentId && !transport) {
15088
+ throw new Error(withUsage$p('The `agentId` option is required unless a custom `transport` is provided.'));
15089
+ }
15090
+ if (!task) {
15091
+ throw new Error(withUsage$p('The `task` option is required.'));
15092
+ }
15093
+ var runner;
15094
+ var output;
15095
+ var isLoading = false;
15096
+ var error;
15097
+ var disposed = false;
15098
+ var triggerRender = noop;
15099
+ var requestId = 0;
15100
+ var submit = function submit(variables) {
15101
+ if (disposed) return Promise.resolve(undefined);
15102
+ var currentRequestId = requestId += 1;
15103
+ var isStale = function isStale() {
15104
+ return disposed || currentRequestId !== requestId;
15105
+ };
15106
+ // Clear the previous output so consumers can show a loading state
15107
+ // rather than stale data while the new request is in flight.
15108
+ output = undefined;
15109
+ error = undefined;
15110
+ isLoading = true;
15111
+ triggerRender();
15112
+ return Promise.resolve().then(function() {
15113
+ return runner.submit(variables, {
15114
+ onData: stream ? function(partial) {
15115
+ if (isStale()) return;
15116
+ output = partial;
15117
+ triggerRender();
15118
+ } : undefined
15119
+ });
15120
+ }).then(function(next) {
15121
+ var result = next;
15122
+ if (!isStale()) {
15123
+ output = result;
15124
+ }
15125
+ return result;
15126
+ }).catch(function(err) {
15127
+ if (!isStale()) {
15128
+ output = undefined;
15129
+ error = _instanceof(err, Error) ? err : new Error(String(err));
15130
+ }
15131
+ return undefined;
15132
+ }).finally(function() {
15133
+ if (isStale()) return;
15134
+ isLoading = false;
15135
+ triggerRender();
15136
+ });
15137
+ };
15138
+ var invalidate = function invalidate() {
15139
+ if (disposed) return;
15140
+ // Bump the request id so any in-flight request's callbacks see
15141
+ // `isStale()` and are ignored. The fetch itself is left to complete.
15142
+ requestId += 1;
15143
+ isLoading = false;
15144
+ triggerRender();
15145
+ };
15146
+ var getWidgetRenderState = function getWidgetRenderState() {
15147
+ return {
15148
+ output: output,
15149
+ isLoading: isLoading,
15150
+ error: error,
15151
+ submit: submit,
15152
+ invalidate: invalidate,
15153
+ widgetParams: widgetParams
15154
+ };
15155
+ };
15156
+ return {
15157
+ $$type: 'ais.tasks',
15158
+ init: function init(initOptions) {
15159
+ var instantSearchInstance = initOptions.instantSearchInstance;
15160
+ if (transport) {
15161
+ var resolved = resolveEndpoint({
15162
+ transport: transport
15163
+ });
15164
+ runner = createTaskRunner({
15165
+ endpoint: resolved.endpoint,
15166
+ headers: resolved.headers,
15167
+ task: task,
15168
+ stream: stream,
15169
+ prepareRequest: resolved.prepareSendMessagesRequest
15170
+ });
15171
+ } else {
15172
+ var _getAppIdAndApiKey = _sliced_to_array(getAppIdAndApiKey(instantSearchInstance.client), 2), appId = _getAppIdAndApiKey[0], apiKey = _getAppIdAndApiKey[1];
15173
+ if (!appId || !apiKey) {
15174
+ throw new Error(withUsage$p('Could not extract Algolia credentials from the search client.'));
15175
+ }
15176
+ var resolved1 = resolveEndpoint({
15177
+ appId: appId,
15178
+ apiKey: apiKey,
15179
+ agentId: agentId,
15180
+ algoliaAgent: getAlgoliaAgent(instantSearchInstance.client)
15181
+ });
15182
+ runner = createTaskRunner({
15183
+ endpoint: resolved1.endpoint,
15184
+ headers: resolved1.headers,
15185
+ task: task,
15186
+ stream: stream
15187
+ });
15188
+ }
15189
+ triggerRender = function triggerRender() {
15190
+ renderFn(_object_spread_props(_object_spread({}, getWidgetRenderState()), {
15191
+ instantSearchInstance: instantSearchInstance
15192
+ }), false);
15193
+ };
15194
+ renderFn(_object_spread_props(_object_spread({}, getWidgetRenderState()), {
15195
+ instantSearchInstance: instantSearchInstance
15196
+ }), true);
15197
+ },
15198
+ render: function render(renderOptions) {
15199
+ renderFn(_object_spread_props(_object_spread({}, getWidgetRenderState()), {
15200
+ instantSearchInstance: renderOptions.instantSearchInstance
15201
+ }), false);
15202
+ },
15203
+ dispose: function dispose() {
15204
+ disposed = true;
15205
+ unmountFn();
15206
+ }
15207
+ };
15208
+ };
15209
+ };
15210
+
15211
+ var withUsage$o = createDocumentationMessageGenerator({
15212
+ name: 'prompt-suggestions',
15213
+ connector: true
15214
+ });
15215
+ var RENDER_STATE_KEY = 'promptSuggestions';
15216
+ var CHAT_RENDER_STATE_KEY = 'chat';
15217
+ var DEBOUNCE_MS = 300;
15218
+ function parseSuggestions(data) {
15219
+ var suggestions = data === null || data === void 0 ? void 0 : data.suggestions;
15220
+ if (!Array.isArray(suggestions)) {
15221
+ return [];
15222
+ }
15223
+ return suggestions.filter(function(s) {
15224
+ return typeof s === 'string';
15225
+ });
15226
+ }
15227
+ function buildSuggestionMessage(suggestion) {
15228
+ return "The user clicked this on-page suggestion. Use the current page context first, then search only if needed.\n\nSuggestion: ".concat(suggestion);
15229
+ }
15230
+ function stripInternalHitMetadata(hit) {
15231
+ var clean = {};
15232
+ Object.keys(hit).forEach(function(key) {
15233
+ // Strip internal metadata, which is `_`-prefixed
15234
+ // (`_highlightResult`, `_rankingInfo`, `__position`, …).
15235
+ if (!key.startsWith('_')) {
15236
+ clean[key] = hit[key];
15237
+ }
15238
+ });
15239
+ return clean;
15240
+ }
15241
+ var DEFAULT_TRANSFORM_HITS = function DEFAULT_TRANSFORM_HITS(hits) {
15242
+ return hits.slice(0, 5).map(stripInternalHitMetadata);
15243
+ };
15244
+ function buildFilters(results) {
15245
+ var state = results._state;
15246
+ if (!state) {
15247
+ return undefined;
15248
+ }
15249
+ var groups = [];
15250
+ var disjunctiveGroups = {};
15251
+ getRefinements(results, state).forEach(function(refinement) {
15252
+ if (refinement.type === 'numeric') {
15253
+ groups.push([
15254
+ "".concat(refinement.attribute).concat(refinement.operator).concat(refinement.numericValue)
15255
+ ]);
15256
+ return;
15257
+ }
15258
+ var value = refinement.type === 'exclude' ? "".concat(refinement.attribute, ":-").concat(refinement.name) : "".concat(refinement.attribute, ":").concat(refinement.name);
15259
+ if (refinement.type === 'disjunctive') {
15260
+ var group = disjunctiveGroups[refinement.attribute];
15261
+ if (group) {
15262
+ group.push(value);
15263
+ } else {
15264
+ var newGroup = [
15265
+ value
15266
+ ];
15267
+ disjunctiveGroups[refinement.attribute] = newGroup;
15268
+ groups.push(newGroup);
15269
+ }
15270
+ return;
15271
+ }
15272
+ groups.push([
15273
+ value
15274
+ ]);
15275
+ });
15276
+ return groups.length > 0 ? groups : undefined;
15277
+ }
15278
+ var connectPromptSuggestions = function connectPromptSuggestions(renderFn) {
15279
+ var unmountFn = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : noop;
15280
+ checkRendering(renderFn, withUsage$o());
15281
+ return function(widgetParams) {
15282
+ var agentId = widgetParams.agentId, configurationId = widgetParams.configurationId, _widgetParams_transformHits = widgetParams.transformHits, transformHits = _widgetParams_transformHits === void 0 ? DEFAULT_TRANSFORM_HITS : _widgetParams_transformHits, context = widgetParams.context, _widgetParams_transformItems = widgetParams.transformItems, transformItems = _widgetParams_transformItems === void 0 ? function(items) {
15283
+ return items;
15284
+ } : _widgetParams_transformItems, transport = widgetParams.transport;
15285
+ if (!agentId && !transport) {
15286
+ throw new Error(withUsage$o('The `agentId` option is required unless a custom `transport` is provided.'));
15287
+ }
15288
+ if (!configurationId) {
15289
+ throw new Error(withUsage$o('The `configurationId` option is required.'));
15290
+ }
15291
+ var tasksState;
15292
+ var suggestions = [];
15293
+ var isLoading = false;
15294
+ var debounceTimer;
15295
+ var lastStateSignature = null;
15296
+ var latestRenderOptions = null;
15297
+ // Set in `dispose()`. A debounced or in-flight `fetch()` can resolve after
15298
+ // the widget is unmounted; this guard stops those late callbacks from
15299
+ // calling `renderFn` into a torn-down container.
15300
+ var disposed = false;
15301
+ // True between a state-signature change and the debounced refetch that
15302
+ // follows it. While pending, the search state has already moved on, so a
15303
+ // still-in-flight request from the previous state must not paint its
15304
+ // suggestions, its inner render is ignored until the new `submit` starts.
15305
+ var refetchPending = false;
15306
+ var getStateSignature = function getStateSignature(results) {
15307
+ var _buildFilters;
15308
+ if (results.queryID) {
15309
+ return results.queryID;
15310
+ }
15311
+ var query = results.query || '';
15312
+ var filters = JSON.stringify((_buildFilters = buildFilters(results)) !== null && _buildFilters !== void 0 ? _buildFilters : []);
15313
+ var hitIds = (results.hits || []).map(function(hit) {
15314
+ return hit.objectID;
15315
+ }).join(',');
15316
+ return "".concat(query, "|").concat(filters, "|").concat(hitIds);
15317
+ };
15318
+ var getChatRenderState = function getChatRenderState(renderOptions) {
15319
+ var _instantSearchInstance_renderState;
15320
+ var instantSearchInstance = renderOptions.instantSearchInstance, parent = renderOptions.parent;
15321
+ var indexId = parent ? parent.getIndexId() : '';
15322
+ if (!indexId || !((_instantSearchInstance_renderState = instantSearchInstance.renderState) === null || _instantSearchInstance_renderState === void 0 ? void 0 : _instantSearchInstance_renderState[indexId])) {
15323
+ return undefined;
15324
+ }
15325
+ return instantSearchInstance.renderState[indexId][CHAT_RENDER_STATE_KEY];
15326
+ };
15327
+ var sendToChat = function sendToChat(renderOptions) {
15328
+ return function(prompt) {
15329
+ var _ref, _ref1;
15330
+ var chatRenderState = getChatRenderState(renderOptions);
15331
+ if (!chatRenderState || !chatRenderState.sendMessage) {
15332
+ return false;
15333
+ }
15334
+ var results = (_ref = (_ref1 = latestRenderOptions === null || latestRenderOptions === void 0 ? void 0 : latestRenderOptions.results) !== null && _ref1 !== void 0 ? _ref1 : 'results' in renderOptions ? renderOptions.results : null) !== null && _ref !== void 0 ? _ref : null;
15335
+ return openChat(chatRenderState, {
15336
+ message: buildSuggestionMessage(prompt),
15337
+ referer: 'prompt-suggestions-widget',
15338
+ turnContext: buildTurnContext(results)
15339
+ });
15340
+ };
15341
+ };
15342
+ var resolvePageContext = function resolvePageContext(results) {
15343
+ var resolvedContext = typeof context === 'function' ? context() : context;
15344
+ // Explicit context replaces auto-extraction; otherwise derive it from
15345
+ // the current search state. The task's server-owned instructions decide
15346
+ // how to interpret the shape — the client doesn't label it.
15347
+ if (resolvedContext) {
15348
+ return _object_spread({}, resolvedContext);
15349
+ }
15350
+ if (!results) {
15351
+ return undefined;
15352
+ }
15353
+ var filters = buildFilters(results);
15354
+ return _object_spread_props(_object_spread({
15355
+ query: results.query || ''
15356
+ }, filters ? {
15357
+ filters: filters
15358
+ } : {}), {
15359
+ hitsSample: transformHits(results.hits)
15360
+ });
15361
+ };
15362
+ var buildInput = function buildInput(results) {
15363
+ var _resolvePageContext;
15364
+ return (_resolvePageContext = resolvePageContext(results)) !== null && _resolvePageContext !== void 0 ? _resolvePageContext : {};
15365
+ };
15366
+ // The same page context, flattened for the chat handoff: `turnContext` is
15367
+ // a flat `Record<string, string>` per the Agent Studio contract, so
15368
+ // non-string values (e.g. `hitsSample`) are serialized.
15369
+ var buildTurnContext = function buildTurnContext(results) {
15370
+ var pageContext = resolvePageContext(results);
15371
+ if (!pageContext) {
15372
+ return undefined;
15373
+ }
15374
+ var entries = Object.entries(pageContext).map(function(param) {
15375
+ var _param = _sliced_to_array(param, 2), key = _param[0], value = _param[1];
15376
+ return [
15377
+ key,
15378
+ typeof value === 'string' ? value : JSON.stringify(value)
15379
+ ];
15380
+ }).filter(function(param) {
15381
+ var _param = _sliced_to_array(param, 2), value = _param[1];
15382
+ return value.trim() !== '';
15383
+ });
15384
+ return entries.length > 0 ? Object.fromEntries(entries) : undefined;
15385
+ };
15386
+ var renderOutward = function renderOutward(renderOptions) {
15387
+ if (disposed) return;
15388
+ renderFn(_object_spread_props(_object_spread({}, getWidgetRenderState(renderOptions)), {
15389
+ instantSearchInstance: renderOptions.instantSearchInstance
15390
+ }), false);
15391
+ };
15392
+ var fetchAndRender = function fetchAndRender(results, renderOptions) {
15393
+ var _results_hits;
15394
+ if (disposed || !tasksState) return;
15395
+ refetchPending = false;
15396
+ var hasContext = context !== undefined;
15397
+ if (!hasContext && !(results === null || results === void 0 ? void 0 : (_results_hits = results.hits) === null || _results_hits === void 0 ? void 0 : _results_hits.length)) {
15398
+ tasksState.invalidate();
15399
+ suggestions = [];
15400
+ isLoading = false;
15401
+ renderOutward(renderOptions);
15402
+ return;
15403
+ }
15404
+ tasksState.submit(buildInput(results));
15405
+ };
15406
+ var refresh = function refresh() {
15407
+ if (isLoading) return;
15408
+ var results = latestRenderOptions === null || latestRenderOptions === void 0 ? void 0 : latestRenderOptions.results;
15409
+ if (!results || !latestRenderOptions) return;
15410
+ clearTimeout(debounceTimer);
15411
+ lastStateSignature = getStateSignature(results);
15412
+ fetchAndRender(results, latestRenderOptions);
15413
+ };
15414
+ var getWidgetRenderState = function getWidgetRenderState(renderOptions) {
15415
+ var results = 'results' in renderOptions ? renderOptions.results : undefined;
15416
+ var transformed = transformItems(suggestions, {
15417
+ query: (results === null || results === void 0 ? void 0 : results.query) || '',
15418
+ results: results || null
15419
+ });
15420
+ var chatRenderState = getChatRenderState(renderOptions);
15421
+ var isChatBusy$1 = chatRenderState ? !chatRenderState.sendMessage || isChatBusy(chatRenderState) : false;
15422
+ var send = sendToChat(renderOptions);
15423
+ return {
15424
+ suggestions: transformed,
15425
+ isLoading: isLoading,
15426
+ onSuggestionClick: send,
15427
+ sendToChat: send,
15428
+ refresh: refresh,
15429
+ isChatBusy: isChatBusy$1,
15430
+ widgetParams: widgetParams
15431
+ };
15432
+ };
15433
+ // Mirrors each inner render (submit start → skeleton, stream partials,
15434
+ // resolve/error) into this widget's state and re-renders on the client.
15435
+ var handleInnerRender = function handleInnerRender(renderState) {
15436
+ tasksState = renderState;
15437
+ if (refetchPending) return;
15438
+ if (renderState.error) {
15439
+ // A failed task (including a mid-stream `error` event) must not leave
15440
+ // any streamed partial visible. There's no error UI for now, so fall
15441
+ // back to a blank suggestions state.
15442
+ suggestions = [];
15443
+ } else if (renderState.isLoading || renderState.output !== undefined) {
15444
+ // Only adopt the inner output once a request is loading or has
15445
+ // produced one, so the initial no-op render doesn't clobber pills.
15446
+ suggestions = parseSuggestions(renderState.output);
15447
+ }
15448
+ isLoading = renderState.isLoading;
15449
+ if (!latestRenderOptions) return;
15450
+ renderOutward(latestRenderOptions);
15451
+ };
15452
+ var tasksWidget = connectTasks(handleInnerRender, noop)(_object_spread_props(_object_spread({}, transport ? {
15453
+ transport: transport
15454
+ } : {
15455
+ agentId: agentId
15456
+ }), {
15457
+ task: configurationId,
15458
+ stream: true
15459
+ }));
15460
+ return {
15461
+ $$type: 'ais.promptSuggestions',
15462
+ init: function init(initOptions) {
15463
+ var instantSearchInstance = initOptions.instantSearchInstance;
15464
+ tasksWidget.init(initOptions);
15465
+ renderFn(_object_spread_props(_object_spread({}, getWidgetRenderState(initOptions)), {
15466
+ instantSearchInstance: instantSearchInstance
15467
+ }), true);
15468
+ },
15469
+ render: function render(renderOptions) {
15470
+ var results = renderOptions.results, instantSearchInstance = renderOptions.instantSearchInstance;
15471
+ latestRenderOptions = renderOptions;
15472
+ if (!results) {
15473
+ renderFn(_object_spread_props(_object_spread({}, getWidgetRenderState(renderOptions)), {
15474
+ instantSearchInstance: instantSearchInstance
15475
+ }), false);
15476
+ return;
15477
+ }
15478
+ var stateSignature = getStateSignature(results);
15479
+ if (stateSignature !== lastStateSignature) {
15480
+ lastStateSignature = stateSignature;
15481
+ refetchPending = true;
15482
+ clearTimeout(debounceTimer);
15483
+ debounceTimer = setTimeout(function() {
15484
+ if (latestRenderOptions === null || latestRenderOptions === void 0 ? void 0 : latestRenderOptions.results) {
15485
+ fetchAndRender(latestRenderOptions.results, latestRenderOptions);
15486
+ }
15487
+ }, DEBOUNCE_MS);
15488
+ }
15489
+ renderFn(_object_spread_props(_object_spread({}, getWidgetRenderState(renderOptions)), {
15490
+ instantSearchInstance: instantSearchInstance
15491
+ }), false);
15492
+ },
15493
+ dispose: function dispose(disposeOptions) {
15494
+ disposed = true;
15495
+ clearTimeout(debounceTimer);
15496
+ tasksWidget.dispose(disposeOptions);
15497
+ unmountFn();
15498
+ },
15499
+ getRenderState: function getRenderState(renderState, renderOptions) {
15500
+ return _object_spread_props(_object_spread({}, renderState), _define_property({}, RENDER_STATE_KEY, this.getWidgetRenderState(renderOptions)));
15501
+ },
15502
+ getWidgetRenderState: function getWidgetRenderState1(renderOptions) {
15503
+ return getWidgetRenderState(renderOptions);
15504
+ }
15505
+ };
15506
+ };
15507
+ };
15508
+
15509
+ function usePromptSuggestions(props, additionalWidgetProperties) {
15510
+ return useConnector(connectPromptSuggestions, props, additionalWidgetProperties);
14807
15511
  }
14808
15512
 
14809
15513
  var withUsage$n = createDocumentationMessageGenerator({
@@ -19048,6 +19752,7 @@
19048
19752
  exports.useNumericMenu = useNumericMenu;
19049
19753
  exports.usePagination = usePagination;
19050
19754
  exports.usePoweredBy = usePoweredBy;
19755
+ exports.usePromptSuggestions = usePromptSuggestions;
19051
19756
  exports.useQueryRules = useQueryRules;
19052
19757
  exports.useRSCContext = useRSCContext;
19053
19758
  exports.useRange = useRange;