instantsearch.js 4.86.1 → 4.87.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.
Files changed (82) hide show
  1. package/cjs/connectors/autocomplete/connectAutocomplete.js +13 -5
  2. package/cjs/connectors/chat/connectChat.js +92 -20
  3. package/cjs/connectors/filter-suggestions/connectFilterSuggestions.js +255 -0
  4. package/cjs/connectors/index.js +7 -0
  5. package/cjs/connectors/index.umd.js +7 -0
  6. package/cjs/index.js +2 -2
  7. package/cjs/lib/ai-lite/abstract-chat.js +823 -0
  8. package/cjs/lib/ai-lite/index.js +57 -0
  9. package/cjs/lib/ai-lite/stream-parser.js +138 -0
  10. package/cjs/lib/ai-lite/transport.js +218 -0
  11. package/cjs/lib/ai-lite/types.js +1 -0
  12. package/cjs/lib/ai-lite/utils.js +85 -0
  13. package/cjs/lib/chat/chat.js +6 -6
  14. package/cjs/lib/chat/index.js +5 -2
  15. package/cjs/lib/version.js +1 -1
  16. package/cjs/widgets/autocomplete/autocomplete.js +15 -6
  17. package/cjs/widgets/chat/chat.js +32 -3
  18. package/cjs/widgets/filter-suggestions/filter-suggestions.js +131 -0
  19. package/cjs/widgets/index.js +7 -0
  20. package/cjs/widgets/index.umd.js +7 -0
  21. package/dist/instantsearch.development.d.ts +2551 -346
  22. package/dist/instantsearch.development.js +9408 -4314
  23. package/dist/instantsearch.development.js.map +1 -1
  24. package/dist/instantsearch.production.d.ts +2551 -346
  25. package/dist/instantsearch.production.min.d.ts +2551 -346
  26. package/dist/instantsearch.production.min.js +2 -2
  27. package/dist/instantsearch.production.min.js.map +1 -1
  28. package/es/connectors/autocomplete/connectAutocomplete.d.ts +10 -0
  29. package/es/connectors/autocomplete/connectAutocomplete.js +13 -5
  30. package/es/connectors/chat/connectChat.d.ts +24 -14
  31. package/es/connectors/chat/connectChat.js +90 -18
  32. package/es/connectors/filter-suggestions/connectFilterSuggestions.d.ts +95 -0
  33. package/es/connectors/filter-suggestions/connectFilterSuggestions.js +249 -0
  34. package/es/connectors/frequently-bought-together/connectFrequentlyBoughtTogether.d.ts +2 -2
  35. package/es/connectors/geo-search/connectGeoSearch.d.ts +1 -1
  36. package/es/connectors/hits/connectHits.d.ts +1 -1
  37. package/es/connectors/hits/connectHitsWithInsights.d.ts +1 -1
  38. package/es/connectors/index.d.ts +1 -0
  39. package/es/connectors/index.js +2 -1
  40. package/es/connectors/index.umd.d.ts +1 -0
  41. package/es/connectors/index.umd.js +2 -1
  42. package/es/connectors/infinite-hits/connectInfiniteHits.d.ts +1 -1
  43. package/es/connectors/infinite-hits/connectInfiniteHitsWithInsights.d.ts +1 -1
  44. package/es/connectors/looking-similar/connectLookingSimilar.d.ts +2 -2
  45. package/es/connectors/related-products/connectRelatedProducts.d.ts +2 -2
  46. package/es/connectors/trending-items/connectTrendingItems.d.ts +2 -2
  47. package/es/lib/ai-lite/abstract-chat.d.ts +89 -0
  48. package/es/lib/ai-lite/abstract-chat.js +818 -0
  49. package/es/lib/ai-lite/index.d.ts +11 -0
  50. package/es/lib/ai-lite/index.js +18 -0
  51. package/es/lib/ai-lite/stream-parser.d.ts +18 -0
  52. package/es/lib/ai-lite/stream-parser.js +131 -0
  53. package/es/lib/ai-lite/transport.d.ts +24 -0
  54. package/es/lib/ai-lite/transport.js +214 -0
  55. package/es/lib/ai-lite/types.d.ts +362 -0
  56. package/es/lib/ai-lite/types.js +1 -0
  57. package/es/lib/ai-lite/utils.d.ts +12 -0
  58. package/es/lib/ai-lite/utils.js +76 -0
  59. package/es/lib/chat/chat.d.ts +3 -3
  60. package/es/lib/chat/chat.js +4 -4
  61. package/es/lib/chat/index.d.ts +3 -0
  62. package/es/lib/chat/index.js +4 -1
  63. package/es/lib/version.d.ts +1 -1
  64. package/es/lib/version.js +1 -1
  65. package/es/widgets/autocomplete/autocomplete.d.ts +2 -1
  66. package/es/widgets/autocomplete/autocomplete.js +15 -6
  67. package/es/widgets/chat/chat.d.ts +22 -14
  68. package/es/widgets/chat/chat.js +33 -4
  69. package/es/widgets/filter-suggestions/filter-suggestions.d.ts +689 -0
  70. package/es/widgets/filter-suggestions/filter-suggestions.js +124 -0
  71. package/es/widgets/frequently-bought-together/frequently-bought-together.d.ts +3 -3
  72. package/es/widgets/geo-search/geo-search.d.ts +1 -1
  73. package/es/widgets/hits/hits.d.ts +1 -1
  74. package/es/widgets/index.d.ts +1 -0
  75. package/es/widgets/index.js +2 -1
  76. package/es/widgets/index.umd.d.ts +1 -0
  77. package/es/widgets/index.umd.js +2 -1
  78. package/es/widgets/infinite-hits/infinite-hits.d.ts +1 -1
  79. package/es/widgets/looking-similar/looking-similar.d.ts +3 -3
  80. package/es/widgets/related-products/related-products.d.ts +3 -3
  81. package/es/widgets/trending-items/trending-items.d.ts +3 -3
  82. package/package.json +6 -7
@@ -21,7 +21,11 @@ var connectAutocomplete = function connectAutocomplete(renderFn) {
21
21
  return function (widgetParams) {
22
22
  var _ref = widgetParams || {},
23
23
  _ref$escapeHTML = _ref.escapeHTML,
24
- escapeHTML = _ref$escapeHTML === void 0 ? true : _ref$escapeHTML;
24
+ escapeHTML = _ref$escapeHTML === void 0 ? true : _ref$escapeHTML,
25
+ _ref$transformItems = _ref.transformItems,
26
+ transformItems = _ref$transformItems === void 0 ? function (indices) {
27
+ return indices;
28
+ } : _ref$transformItems;
25
29
  process.env.NODE_ENV === 'development' ? (0, _utils.warning)(!widgetParams.indices, "\nThe option `indices` has been removed from the Autocomplete connector.\n\nThe indices to target are now inferred from the widgets tree.\n".concat(Array.isArray(widgetParams.indices) ? "\nAn alternative would be:\n\nconst autocomplete = connectAutocomplete(renderer);\n\nsearch.addWidgets([\n ".concat(widgetParams.indices.map(function (_ref2) {
26
30
  var value = _ref2.value;
27
31
  return "index({ indexName: '".concat(value, "' }),");
@@ -63,6 +67,7 @@ var connectAutocomplete = function connectAutocomplete(renderFn) {
63
67
  helper.setQuery(query).search();
64
68
  };
65
69
  }
70
+ var sendEventMap = {};
66
71
  var indices = scopedResults.map(function (scopedResult) {
67
72
  var _scopedResult$results, _scopedResult$results2;
68
73
  // We need to escape the hits because highlighting
@@ -70,7 +75,7 @@ var connectAutocomplete = function connectAutocomplete(renderFn) {
70
75
  if (scopedResult.results) {
71
76
  scopedResult.results.hits = escapeHTML ? (0, _utils.escapeHits)(scopedResult.results.hits) : scopedResult.results.hits;
72
77
  }
73
- var sendEvent = (0, _utils.createSendEventForHits)({
78
+ sendEventMap[scopedResult.indexId] = (0, _utils.createSendEventForHits)({
74
79
  instantSearchInstance: instantSearchInstance,
75
80
  helper: scopedResult.helper,
76
81
  widgetType: _this.$$type
@@ -79,13 +84,16 @@ var connectAutocomplete = function connectAutocomplete(renderFn) {
79
84
  indexId: scopedResult.indexId,
80
85
  indexName: ((_scopedResult$results = scopedResult.results) === null || _scopedResult$results === void 0 ? void 0 : _scopedResult$results.index) || '',
81
86
  hits: ((_scopedResult$results2 = scopedResult.results) === null || _scopedResult$results2 === void 0 ? void 0 : _scopedResult$results2.hits) || [],
82
- results: scopedResult.results || {},
83
- sendEvent: sendEvent
87
+ results: scopedResult.results || {}
84
88
  };
85
89
  });
86
90
  return {
87
91
  currentRefinement: state.query || '',
88
- indices: indices,
92
+ indices: transformItems(indices).map(function (transformedIndex) {
93
+ return _objectSpread(_objectSpread({}, transformedIndex), {}, {
94
+ sendEvent: sendEventMap[transformedIndex.indexId]
95
+ });
96
+ }),
89
97
  refine: connectorState.refine,
90
98
  widgetParams: widgetParams
91
99
  };
@@ -5,10 +5,11 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.default = void 0;
8
- var _ai = require("ai");
8
+ var _aiLite = require("../../lib/ai-lite");
9
9
  var _chat = require("../../lib/chat");
10
10
  var _utils = require("../../lib/utils");
11
- var _excluded = ["resume", "tools"];
11
+ var _excluded = ["resume", "tools", "type"],
12
+ _excluded2 = ["messages", "trigger"];
12
13
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
13
14
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
14
15
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
@@ -16,10 +17,14 @@ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol"
16
17
  function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
17
18
  function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
18
19
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
19
- function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
20
- function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
21
20
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
22
21
  function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
22
+ function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
23
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
24
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
25
+ function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
26
+ function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
27
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
23
28
  function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
24
29
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
25
30
  var withUsage = (0, _utils.createDocumentationMessageGenerator)({
@@ -36,6 +41,8 @@ var connectChat = exports.default = function connectChat(renderFn) {
36
41
  resume = _ref$resume === void 0 ? false : _ref$resume,
37
42
  _ref$tools = _ref.tools,
38
43
  tools = _ref$tools === void 0 ? {} : _ref$tools,
44
+ _ref$type = _ref.type,
45
+ type = _ref$type === void 0 ? 'chat' : _ref$type,
39
46
  options = _objectWithoutProperties(_ref, _excluded);
40
47
  var _chatInstance;
41
48
  var input = '';
@@ -45,6 +52,25 @@ var connectChat = exports.default = function connectChat(renderFn) {
45
52
  var setInput;
46
53
  var setOpen;
47
54
  var setIsClearing;
55
+ var agentId = 'agentId' in options ? options.agentId : undefined;
56
+
57
+ // Extract suggestions from the last assistant message's data-suggestions part
58
+ var getSuggestionsFromMessages = function getSuggestionsFromMessages(messages) {
59
+ // Find the last assistant message (iterate from end)
60
+ var lastAssistantMessage = _toConsumableArray(messages).reverse().find(function (message) {
61
+ return message.role === 'assistant' && message.parts;
62
+ });
63
+ if (!(lastAssistantMessage !== null && lastAssistantMessage !== void 0 && lastAssistantMessage.parts)) {
64
+ return undefined;
65
+ }
66
+
67
+ // Find the data-suggestions part
68
+ var suggestionsPart = lastAssistantMessage.parts.find(function (part) {
69
+ var _data;
70
+ return 'type' in part && part.type === 'data-suggestions' && 'data' in part && Array.isArray((_data = part.data) === null || _data === void 0 ? void 0 : _data.suggestions);
71
+ });
72
+ return suggestionsPart === null || suggestionsPart === void 0 ? void 0 : suggestionsPart.data.suggestions;
73
+ };
48
74
  var setMessages = function setMessages(messagesParam) {
49
75
  if (typeof messagesParam === 'function') {
50
76
  messagesParam = messagesParam(_chatInstance.messages);
@@ -68,20 +94,67 @@ var connectChat = exports.default = function connectChat(renderFn) {
68
94
  _getAppIdAndApiKey2 = _slicedToArray(_getAppIdAndApiKey, 2),
69
95
  appId = _getAppIdAndApiKey2[0],
70
96
  apiKey = _getAppIdAndApiKey2[1];
97
+
98
+ // Filter out custom data parts (like data-suggestions) that the backend doesn't accept
99
+ var filterDataParts = function filterDataParts(messages) {
100
+ return messages.map(function (message) {
101
+ var _message$parts;
102
+ return _objectSpread(_objectSpread({}, message), {}, {
103
+ parts: (_message$parts = message.parts) === null || _message$parts === void 0 ? void 0 : _message$parts.filter(function (part) {
104
+ return !('type' in part && part.type.startsWith('data-'));
105
+ })
106
+ });
107
+ });
108
+ };
71
109
  if ('transport' in options && options.transport) {
72
- transport = new _ai.DefaultChatTransport(options.transport);
110
+ var originalPrepare = options.transport.prepareSendMessagesRequest;
111
+ transport = new _aiLite.DefaultChatTransport(_objectSpread(_objectSpread({}, options.transport), {}, {
112
+ prepareSendMessagesRequest: function prepareSendMessagesRequest(params) {
113
+ // Call the original prepareSendMessagesRequest if it exists,
114
+ // otherwise construct the default body
115
+ var preparedOrPromise = originalPrepare ? originalPrepare(params) : {
116
+ body: _objectSpread({}, params)
117
+ };
118
+ // Then filter out data-* parts
119
+ var applyFilter = function applyFilter(prepared) {
120
+ return _objectSpread(_objectSpread({}, prepared), {}, {
121
+ body: _objectSpread(_objectSpread({}, prepared.body), {}, {
122
+ messages: filterDataParts(prepared.body.messages)
123
+ })
124
+ });
125
+ };
126
+
127
+ // Handle both sync and async cases
128
+ if (preparedOrPromise && 'then' in preparedOrPromise) {
129
+ return preparedOrPromise.then(applyFilter);
130
+ }
131
+ return applyFilter(preparedOrPromise);
132
+ }
133
+ }));
73
134
  }
74
135
  if ('agentId' in options && options.agentId) {
75
- var agentId = options.agentId;
76
136
  if (!appId || !apiKey) {
77
137
  throw new Error(withUsage('Could not extract Algolia credentials from the search client.'));
78
138
  }
79
- transport = new _ai.DefaultChatTransport({
80
- api: "https://".concat(appId, ".algolia.net/agent-studio/1/agents/").concat(agentId, "/completions?compatibilityMode=ai-sdk-5"),
139
+ var baseApi = "https://".concat(appId, ".algolia.net/agent-studio/1/agents/").concat(agentId, "/completions?compatibilityMode=ai-sdk-5");
140
+ transport = new _aiLite.DefaultChatTransport({
141
+ api: baseApi,
81
142
  headers: {
82
143
  'x-algolia-application-id': appId,
83
144
  'x-algolia-api-Key': apiKey,
84
145
  'x-algolia-agent': (0, _utils.getAlgoliaAgent)(instantSearchInstance.client)
146
+ },
147
+ prepareSendMessagesRequest: function prepareSendMessagesRequest(_ref2) {
148
+ var messages = _ref2.messages,
149
+ trigger = _ref2.trigger,
150
+ rest = _objectWithoutProperties(_ref2, _excluded2);
151
+ return {
152
+ // Bypass cache when regenerating to ensure fresh responses
153
+ api: trigger === 'regenerate-message' ? "".concat(baseApi, "&cache=false") : baseApi,
154
+ body: _objectSpread(_objectSpread({}, rest), {}, {
155
+ messages: filterDataParts(messages)
156
+ })
157
+ };
85
158
  }
86
159
  });
87
160
  }
@@ -93,9 +166,9 @@ var connectChat = exports.default = function connectChat(renderFn) {
93
166
  }
94
167
  return new _chat.Chat(_objectSpread(_objectSpread({}, options), {}, {
95
168
  transport: transport,
96
- sendAutomaticallyWhen: _ai.lastAssistantMessageIsCompleteWithToolCalls,
97
- onToolCall: function onToolCall(_ref2) {
98
- var toolCall = _ref2.toolCall;
169
+ sendAutomaticallyWhen: _aiLite.lastAssistantMessageIsCompleteWithToolCalls,
170
+ onToolCall: function onToolCall(_ref3) {
171
+ var toolCall = _ref3.toolCall;
99
172
  var tool = tools[toolCall.toolName];
100
173
  if (!tool) {
101
174
  if (process.env.NODE_ENV === 'development') {
@@ -108,8 +181,8 @@ var connectChat = exports.default = function connectChat(renderFn) {
108
181
  });
109
182
  }
110
183
  if (tool.onToolCall) {
111
- var addToolResult = function addToolResult(_ref3) {
112
- var output = _ref3.output;
184
+ var addToolResult = function addToolResult(_ref4) {
185
+ var output = _ref4.output;
113
186
  return _chatInstance.addToolResult({
114
187
  output: output,
115
188
  tool: toolCall.toolName,
@@ -165,9 +238,7 @@ var connectChat = exports.default = function connectChat(renderFn) {
165
238
  getRenderState: function getRenderState(renderState, renderOptions
166
239
  // Type is explicitly redefined, to avoid having the TWidgetParams type in the definition
167
240
  ) {
168
- return _objectSpread(_objectSpread({}, renderState), {}, {
169
- chat: this.getWidgetRenderState(renderOptions)
170
- });
241
+ return _objectSpread(_objectSpread({}, renderState), {}, _defineProperty({}, type, this.getWidgetRenderState(renderOptions)));
171
242
  },
172
243
  getWidgetRenderState: function getWidgetRenderState(renderOptions) {
173
244
  var instantSearchInstance = renderOptions.instantSearchInstance,
@@ -186,10 +257,10 @@ var connectChat = exports.default = function connectChat(renderFn) {
186
257
  });
187
258
  }
188
259
  var toolsWithAddToolResult = {};
189
- Object.entries(tools).forEach(function (_ref4) {
190
- var _ref5 = _slicedToArray(_ref4, 2),
191
- key = _ref5[0],
192
- tool = _ref5[1];
260
+ Object.entries(tools).forEach(function (_ref5) {
261
+ var _ref6 = _slicedToArray(_ref5, 2),
262
+ key = _ref6[0],
263
+ tool = _ref6[1];
193
264
  var toolWithAddToolResult = _objectSpread(_objectSpread({}, tool), {}, {
194
265
  addToolResult: _chatInstance.addToolResult
195
266
  });
@@ -204,6 +275,7 @@ var connectChat = exports.default = function connectChat(renderFn) {
204
275
  setInput: setInput,
205
276
  setOpen: setOpen,
206
277
  setMessages: setMessages,
278
+ suggestions: getSuggestionsFromMessages(_chatInstance.messages),
207
279
  isClearing: isClearing,
208
280
  clearMessages: clearMessages,
209
281
  onClearTransitionEnd: onClearTransitionEnd,
@@ -0,0 +1,255 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _utils = require("../../lib/utils");
8
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
9
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
10
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
11
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
12
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
13
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
14
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
15
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
16
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
17
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
18
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
19
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
20
+ var withUsage = (0, _utils.createDocumentationMessageGenerator)({
21
+ name: 'filter-suggestions',
22
+ connector: true
23
+ });
24
+ var connectFilterSuggestions = function connectFilterSuggestions(renderFn) {
25
+ var unmountFn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _utils.noop;
26
+ (0, _utils.checkRendering)(renderFn, withUsage());
27
+ return function (widgetParams) {
28
+ var agentId = widgetParams.agentId,
29
+ attributes = widgetParams.attributes,
30
+ _widgetParams$maxSugg = widgetParams.maxSuggestions,
31
+ maxSuggestions = _widgetParams$maxSugg === void 0 ? 3 : _widgetParams$maxSugg,
32
+ _widgetParams$debounc = widgetParams.debounceMs,
33
+ debounceMs = _widgetParams$debounc === void 0 ? 300 : _widgetParams$debounc,
34
+ _widgetParams$hitsToS = widgetParams.hitsToSample,
35
+ hitsToSample = _widgetParams$hitsToS === void 0 ? 5 : _widgetParams$hitsToS,
36
+ _widgetParams$transfo = widgetParams.transformItems,
37
+ transformItems = _widgetParams$transfo === void 0 ? function (items) {
38
+ return items;
39
+ } : _widgetParams$transfo,
40
+ transport = widgetParams.transport;
41
+ if (!agentId && !transport) {
42
+ throw new Error(withUsage('The `agentId` option is required unless a custom `transport` is provided.'));
43
+ }
44
+ var endpoint;
45
+ var headers;
46
+ var suggestions = [];
47
+ var isLoading = false;
48
+ var debounceTimer;
49
+ var lastStateSignature = null; // null means never fetched
50
+ var refine;
51
+ var searchHelper = null;
52
+ var latestRenderOptions = null;
53
+
54
+ // Create a signature of the current search state (query + refinements)
55
+ var getStateSignature = function getStateSignature(results) {
56
+ var query = results.query || '';
57
+ var refinements = searchHelper ? JSON.stringify(searchHelper.state.facetsRefinements) + JSON.stringify(searchHelper.state.disjunctiveFacetsRefinements) + JSON.stringify(searchHelper.state.hierarchicalFacetsRefinements) : '';
58
+ return "".concat(query, "|").concat(refinements);
59
+ };
60
+ var _getWidgetRenderState = function getWidgetRenderState(renderOptions) {
61
+ var results = 'results' in renderOptions ? renderOptions.results : undefined;
62
+ var transformedSuggestions = transformItems(suggestions, {
63
+ results: results
64
+ });
65
+ return {
66
+ suggestions: transformedSuggestions,
67
+ isLoading: isLoading,
68
+ refine: refine,
69
+ widgetParams: widgetParams
70
+ };
71
+ };
72
+
73
+ // Minimum duration to show skeleton to avoid flash when results are cached
74
+ var MIN_SKELETON_DURATION_MS = 300;
75
+ var fetchSuggestions = function fetchSuggestions(results, renderOptions) {
76
+ var _results$hits, _rawResults$;
77
+ if (!(results !== null && results !== void 0 && (_results$hits = results.hits) !== null && _results$hits !== void 0 && _results$hits.length)) {
78
+ suggestions = [];
79
+ isLoading = false;
80
+ renderFn(_objectSpread(_objectSpread({}, _getWidgetRenderState(renderOptions)), {}, {
81
+ instantSearchInstance: renderOptions.instantSearchInstance
82
+ }), false);
83
+ return;
84
+ }
85
+ var loadingStartTime = Date.now();
86
+ isLoading = true;
87
+ renderFn(_objectSpread(_objectSpread({}, _getWidgetRenderState(renderOptions)), {}, {
88
+ instantSearchInstance: renderOptions.instantSearchInstance
89
+ }), false);
90
+
91
+ // Get facets from raw results (results.facets is processed differently)
92
+ var rawResults = results._rawResults;
93
+ var rawFacets = (rawResults === null || rawResults === void 0 ? void 0 : (_rawResults$ = rawResults[0]) === null || _rawResults$ === void 0 ? void 0 : _rawResults$.facets) || {};
94
+ var facetsToSend = attributes ? Object.fromEntries(Object.entries(rawFacets).filter(function (_ref) {
95
+ var _ref2 = _slicedToArray(_ref, 1),
96
+ key = _ref2[0];
97
+ return attributes.includes(key);
98
+ })) : rawFacets;
99
+
100
+ // Collect current refinements to exclude from suggestions
101
+ var currentRefinements = searchHelper ? (0, _utils.getRefinements)(results, searchHelper.state).map(function (refinement) {
102
+ return {
103
+ attribute: refinement.attribute,
104
+ value: refinement.name
105
+ };
106
+ }) : [];
107
+ var messageText = JSON.stringify({
108
+ query: results.query,
109
+ facets: facetsToSend,
110
+ hitsSample: results.hits.slice(0, hitsToSample),
111
+ currentRefinements: currentRefinements,
112
+ maxSuggestions: maxSuggestions
113
+ });
114
+ var payload = {
115
+ messages: [{
116
+ id: "sr-".concat(Date.now()),
117
+ createdAt: new Date().toISOString(),
118
+ role: 'user',
119
+ parts: [{
120
+ type: 'text',
121
+ text: messageText
122
+ }]
123
+ }]
124
+ };
125
+
126
+ // Apply custom body transformation if provided
127
+ var finalPayload = transport !== null && transport !== void 0 && transport.prepareSendMessagesRequest ? transport.prepareSendMessagesRequest(payload).body : payload;
128
+ fetch(endpoint, {
129
+ method: 'POST',
130
+ headers: _objectSpread(_objectSpread({}, headers), {}, {
131
+ 'Content-Type': 'application/json'
132
+ }),
133
+ body: JSON.stringify(finalPayload)
134
+ }).then(function (response) {
135
+ if (!response.ok) {
136
+ throw new Error("HTTP error ".concat(response.status));
137
+ }
138
+ return response.json();
139
+ }).then(function (data) {
140
+ var parsedSuggestions = JSON.parse(data.parts[1].text);
141
+ var validSuggestions = (Array.isArray(parsedSuggestions) ? parsedSuggestions : []).filter(function (suggestion) {
142
+ if (!(suggestion !== null && suggestion !== void 0 && suggestion.attribute) || !(suggestion !== null && suggestion !== void 0 && suggestion.value) || !(suggestion !== null && suggestion !== void 0 && suggestion.label)) {
143
+ return false;
144
+ }
145
+ // If attributes filter is specified, only allow suggestions for those attributes
146
+ if (attributes && !attributes.includes(suggestion.attribute)) {
147
+ return false;
148
+ }
149
+ return true;
150
+ }).slice(0, maxSuggestions);
151
+ suggestions = validSuggestions;
152
+ }).catch(function () {
153
+ suggestions = [];
154
+ }).finally(function () {
155
+ var elapsed = Date.now() - loadingStartTime;
156
+ var remainingDelay = Math.max(0, MIN_SKELETON_DURATION_MS - elapsed);
157
+ var finishLoading = function finishLoading() {
158
+ isLoading = false;
159
+ renderFn(_objectSpread(_objectSpread({}, _getWidgetRenderState(renderOptions)), {}, {
160
+ instantSearchInstance: renderOptions.instantSearchInstance
161
+ }), false);
162
+ };
163
+ if (remainingDelay > 0) {
164
+ setTimeout(finishLoading, remainingDelay);
165
+ } else {
166
+ finishLoading();
167
+ }
168
+ });
169
+ };
170
+ return {
171
+ $$type: 'ais.filterSuggestions',
172
+ init: function init(initOptions) {
173
+ var instantSearchInstance = initOptions.instantSearchInstance,
174
+ helper = initOptions.helper;
175
+ searchHelper = helper;
176
+ if (transport) {
177
+ // Use custom transport configuration
178
+ endpoint = transport.api;
179
+ headers = transport.headers || {};
180
+ } else {
181
+ // Use default Algolia agent endpoint
182
+ var _getAppIdAndApiKey = (0, _utils.getAppIdAndApiKey)(instantSearchInstance.client),
183
+ _getAppIdAndApiKey2 = _slicedToArray(_getAppIdAndApiKey, 2),
184
+ appId = _getAppIdAndApiKey2[0],
185
+ apiKey = _getAppIdAndApiKey2[1];
186
+ if (!appId || !apiKey) {
187
+ throw new Error(withUsage('Could not extract Algolia credentials from the search client.'));
188
+ }
189
+ endpoint = "https://".concat(appId, ".algolia.net/agent-studio/1/agents/").concat(agentId, "/completions?compatibilityMode=ai-sdk-5&stream=false");
190
+ headers = {
191
+ 'x-algolia-application-id': appId,
192
+ 'x-algolia-api-key': apiKey,
193
+ 'x-algolia-agent': (0, _utils.getAlgoliaAgent)(instantSearchInstance.client)
194
+ };
195
+ }
196
+ refine = function refine(attribute, value) {
197
+ var _helper$state$hierarc;
198
+ // Check if the attribute belongs to a hierarchical facet
199
+ // by finding a hierarchical facet that includes this attribute
200
+ var attr = ((_helper$state$hierarc = helper.state.hierarchicalFacets.find(function (facet) {
201
+ return facet.attributes.includes(attribute);
202
+ })) === null || _helper$state$hierarc === void 0 ? void 0 : _helper$state$hierarc.name) || attribute;
203
+ helper.toggleFacetRefinement(attr, value);
204
+ helper.search();
205
+ };
206
+ renderFn(_objectSpread(_objectSpread({}, _getWidgetRenderState(initOptions)), {}, {
207
+ instantSearchInstance: instantSearchInstance
208
+ }), true);
209
+ },
210
+ render: function render(renderOptions) {
211
+ var results = renderOptions.results,
212
+ instantSearchInstance = renderOptions.instantSearchInstance;
213
+
214
+ // Always store the latest render options
215
+ latestRenderOptions = renderOptions;
216
+ if (!results) {
217
+ renderFn(_objectSpread(_objectSpread({}, _getWidgetRenderState(renderOptions)), {}, {
218
+ instantSearchInstance: instantSearchInstance
219
+ }), false);
220
+ return;
221
+ }
222
+
223
+ // Debounce: only fetch if search state changed (query or refinements) and after delay
224
+ var stateSignature = getStateSignature(results);
225
+ if (stateSignature !== lastStateSignature) {
226
+ lastStateSignature = stateSignature;
227
+ clearTimeout(debounceTimer);
228
+ debounceTimer = setTimeout(function () {
229
+ var _latestRenderOptions;
230
+ // Use the latest render options when the timeout fires
231
+ if ((_latestRenderOptions = latestRenderOptions) !== null && _latestRenderOptions !== void 0 && _latestRenderOptions.results) {
232
+ fetchSuggestions(latestRenderOptions.results, latestRenderOptions);
233
+ }
234
+ }, debounceMs);
235
+ }
236
+ renderFn(_objectSpread(_objectSpread({}, _getWidgetRenderState(renderOptions)), {}, {
237
+ instantSearchInstance: instantSearchInstance
238
+ }), false);
239
+ },
240
+ dispose: function dispose() {
241
+ clearTimeout(debounceTimer);
242
+ unmountFn();
243
+ },
244
+ getRenderState: function getRenderState(renderState, renderOptions) {
245
+ return _objectSpread(_objectSpread({}, renderState), {}, {
246
+ filterSuggestions: this.getWidgetRenderState(renderOptions)
247
+ });
248
+ },
249
+ getWidgetRenderState: function getWidgetRenderState(renderOptions) {
250
+ return _getWidgetRenderState(renderOptions);
251
+ }
252
+ };
253
+ };
254
+ };
255
+ var _default = exports.default = connectFilterSuggestions;
@@ -46,6 +46,12 @@ Object.defineProperty(exports, "connectDynamicWidgets", {
46
46
  return _connectDynamicWidgets.default;
47
47
  }
48
48
  });
49
+ Object.defineProperty(exports, "connectFilterSuggestions", {
50
+ enumerable: true,
51
+ get: function get() {
52
+ return _connectFilterSuggestions.default;
53
+ }
54
+ });
49
55
  Object.defineProperty(exports, "connectFrequentlyBoughtTogether", {
50
56
  enumerable: true,
51
57
  get: function get() {
@@ -231,6 +237,7 @@ var _connectRelevantSort = _interopRequireDefault(require("./relevant-sort/conne
231
237
  var _connectFrequentlyBoughtTogether = _interopRequireDefault(require("./frequently-bought-together/connectFrequentlyBoughtTogether"));
232
238
  var _connectLookingSimilar = _interopRequireDefault(require("./looking-similar/connectLookingSimilar"));
233
239
  var _connectChat = _interopRequireDefault(require("./chat/connectChat"));
240
+ var _connectFilterSuggestions = _interopRequireDefault(require("./filter-suggestions/connectFilterSuggestions"));
234
241
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
235
242
  /** @deprecated answers is no longer supported */
236
243
  var EXPERIMENTAL_connectAnswers = exports.EXPERIMENTAL_connectAnswers = (0, _utils.deprecate)(_connectAnswers.default, 'answers is no longer supported');
@@ -41,6 +41,12 @@ Object.defineProperty(exports, "connectDynamicWidgets", {
41
41
  return _connectDynamicWidgets.default;
42
42
  }
43
43
  });
44
+ Object.defineProperty(exports, "connectFilterSuggestions", {
45
+ enumerable: true,
46
+ get: function get() {
47
+ return _connectFilterSuggestions.default;
48
+ }
49
+ });
44
50
  Object.defineProperty(exports, "connectFrequentlyBoughtTogether", {
45
51
  enumerable: true,
46
52
  get: function get() {
@@ -225,6 +231,7 @@ var _connectVoiceSearch = _interopRequireDefault(require("./voice-search/connect
225
231
  var _connectRelevantSort = _interopRequireDefault(require("./relevant-sort/connectRelevantSort"));
226
232
  var _connectFrequentlyBoughtTogether = _interopRequireDefault(require("./frequently-bought-together/connectFrequentlyBoughtTogether"));
227
233
  var _connectLookingSimilar = _interopRequireDefault(require("./looking-similar/connectLookingSimilar"));
234
+ var _connectFilterSuggestions = _interopRequireDefault(require("./filter-suggestions/connectFilterSuggestions"));
228
235
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
229
236
  /** @deprecated answers is no longer supported */
230
237
  var EXPERIMENTAL_connectAnswers = exports.EXPERIMENTAL_connectAnswers = (0, _utils.deprecate)(_connectAnswers.default, 'answers is no longer supported');
package/cjs/index.js CHANGED
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.default = void 0;
8
- var connectors = _interopRequireWildcard(require("./connectors/index.umd"));
8
+ var connectors = _interopRequireWildcard(require("./connectors/index"));
9
9
  var helpers = _interopRequireWildcard(require("./helpers/index"));
10
10
  var _index3 = require("./lib/infiniteHitsCache/index");
11
11
  var _InstantSearch = _interopRequireDefault(require("./lib/InstantSearch"));
@@ -14,7 +14,7 @@ var stateMappings = _interopRequireWildcard(require("./lib/stateMappings/index")
14
14
  var _version = _interopRequireDefault(require("./lib/version"));
15
15
  var middlewares = _interopRequireWildcard(require("./middlewares/index"));
16
16
  var templates = _interopRequireWildcard(require("./templates/index"));
17
- var widgets = _interopRequireWildcard(require("./widgets/index.umd"));
17
+ var widgets = _interopRequireWildcard(require("./widgets/index"));
18
18
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
19
19
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
20
20
  /**