instantsearch.js 4.54.0 → 4.55.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.
Files changed (104) hide show
  1. package/cjs/components/Hits/Hits.js +16 -7
  2. package/cjs/components/InfiniteHits/InfiniteHits.js +13 -2
  3. package/cjs/components/Pagination/Pagination.js +35 -17
  4. package/cjs/components/Template/Template.js +6 -3
  5. package/cjs/connectors/autocomplete/connectAutocomplete.js +1 -1
  6. package/cjs/connectors/geo-search/connectGeoSearch.js +1 -1
  7. package/cjs/connectors/hierarchical-menu/connectHierarchicalMenu.js +1 -1
  8. package/cjs/connectors/hits/connectHits.js +1 -1
  9. package/cjs/connectors/infinite-hits/connectInfiniteHits.js +39 -31
  10. package/cjs/connectors/menu/connectMenu.js +1 -1
  11. package/cjs/connectors/numeric-menu/connectNumericMenu.js +1 -1
  12. package/cjs/connectors/rating-menu/connectRatingMenu.js +7 -3
  13. package/cjs/connectors/refinement-list/connectRefinementList.js +1 -1
  14. package/cjs/connectors/toggle-refinement/connectToggleRefinement.js +14 -4
  15. package/cjs/helpers/highlight.js +5 -0
  16. package/cjs/helpers/insights.js +3 -4
  17. package/cjs/helpers/reverseHighlight.js +5 -0
  18. package/cjs/helpers/reverseSnippet.js +5 -0
  19. package/cjs/helpers/snippet.js +5 -0
  20. package/cjs/lib/InstantSearch.js +18 -2
  21. package/cjs/lib/insights/listener.js +43 -36
  22. package/cjs/lib/routers/history.js +1 -0
  23. package/cjs/lib/server.js +60 -0
  24. package/cjs/lib/stateMappings/simple.js +1 -0
  25. package/cjs/lib/stateMappings/singleIndex.js +1 -0
  26. package/cjs/lib/utils/createSendEventForFacet.js +12 -2
  27. package/cjs/lib/utils/createSendEventForHits.js +34 -11
  28. package/cjs/lib/utils/index.js +11 -0
  29. package/cjs/lib/utils/walkIndex.js +18 -0
  30. package/cjs/lib/version.js +1 -1
  31. package/cjs/middlewares/createInsightsMiddleware.js +135 -33
  32. package/cjs/middlewares/createMetadataMiddleware.js +17 -5
  33. package/cjs/middlewares/createRouterMiddleware.js +5 -1
  34. package/cjs/widgets/hits/hits.js +1 -2
  35. package/cjs/widgets/infinite-hits/infinite-hits.js +1 -2
  36. package/cjs/widgets/pagination/pagination.js +51 -39
  37. package/cjs/widgets/panel/panel.js +0 -2
  38. package/dist/instantsearch.development.d.ts +94 -12
  39. package/dist/instantsearch.development.js +543 -312
  40. package/dist/instantsearch.development.js.map +1 -1
  41. package/dist/instantsearch.production.d.ts +94 -12
  42. package/dist/instantsearch.production.min.d.ts +94 -12
  43. package/dist/instantsearch.production.min.js +2 -2
  44. package/dist/instantsearch.production.min.js.map +1 -1
  45. package/es/components/Hits/Hits.d.ts +5 -5
  46. package/es/components/Hits/Hits.js +15 -5
  47. package/es/components/InfiniteHits/InfiniteHits.d.ts +3 -2
  48. package/es/components/InfiniteHits/InfiniteHits.js +13 -2
  49. package/es/components/Pagination/Pagination.js +34 -17
  50. package/es/components/Panel/Panel.d.ts +1 -1
  51. package/es/components/Template/Template.js +6 -3
  52. package/es/connectors/autocomplete/connectAutocomplete.js +1 -1
  53. package/es/connectors/geo-search/connectGeoSearch.js +1 -1
  54. package/es/connectors/hierarchical-menu/connectHierarchicalMenu.js +1 -1
  55. package/es/connectors/hits/connectHits.js +1 -1
  56. package/es/connectors/infinite-hits/connectInfiniteHits.js +39 -31
  57. package/es/connectors/menu/connectMenu.js +1 -1
  58. package/es/connectors/numeric-menu/connectNumericMenu.js +1 -1
  59. package/es/connectors/rating-menu/connectRatingMenu.js +7 -3
  60. package/es/connectors/refinement-list/connectRefinementList.js +1 -1
  61. package/es/connectors/toggle-refinement/connectToggleRefinement.js +13 -3
  62. package/es/helpers/highlight.d.ts +3 -0
  63. package/es/helpers/highlight.js +5 -0
  64. package/es/helpers/insights.d.ts +2 -1
  65. package/es/helpers/insights.js +3 -3
  66. package/es/helpers/reverseHighlight.d.ts +3 -0
  67. package/es/helpers/reverseHighlight.js +5 -0
  68. package/es/helpers/reverseSnippet.d.ts +3 -0
  69. package/es/helpers/reverseSnippet.js +5 -0
  70. package/es/helpers/snippet.d.ts +3 -0
  71. package/es/helpers/snippet.js +5 -0
  72. package/es/lib/InstantSearch.d.ts +11 -1
  73. package/es/lib/InstantSearch.js +18 -2
  74. package/es/lib/insights/listener.d.ts +10 -6
  75. package/es/lib/insights/listener.js +42 -36
  76. package/es/lib/routers/history.d.ts +1 -0
  77. package/es/lib/routers/history.js +1 -0
  78. package/es/lib/server.d.ts +10 -0
  79. package/es/lib/server.js +53 -0
  80. package/es/lib/stateMappings/simple.js +1 -0
  81. package/es/lib/stateMappings/singleIndex.js +1 -0
  82. package/es/lib/utils/createSendEventForFacet.js +12 -2
  83. package/es/lib/utils/createSendEventForHits.d.ts +8 -0
  84. package/es/lib/utils/createSendEventForHits.js +33 -11
  85. package/es/lib/utils/index.d.ts +1 -0
  86. package/es/lib/utils/index.js +1 -0
  87. package/es/lib/utils/walkIndex.d.ts +5 -0
  88. package/es/lib/utils/walkIndex.js +12 -0
  89. package/es/lib/version.d.ts +1 -1
  90. package/es/lib/version.js +1 -1
  91. package/es/middlewares/createInsightsMiddleware.d.ts +12 -12
  92. package/es/middlewares/createInsightsMiddleware.js +136 -34
  93. package/es/middlewares/createMetadataMiddleware.d.ts +3 -1
  94. package/es/middlewares/createMetadataMiddleware.js +17 -5
  95. package/es/middlewares/createRouterMiddleware.js +5 -1
  96. package/es/types/insights.d.ts +19 -1
  97. package/es/types/middleware.d.ts +16 -0
  98. package/es/types/router.d.ts +8 -0
  99. package/es/widgets/hits/hits.js +2 -3
  100. package/es/widgets/infinite-hits/infinite-hits.js +2 -3
  101. package/es/widgets/pagination/pagination.d.ts +12 -5
  102. package/es/widgets/pagination/pagination.js +51 -39
  103. package/es/widgets/panel/panel.js +0 -2
  104. package/package.json +6 -6
@@ -6,37 +6,71 @@ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _ty
6
6
  function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
7
7
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
8
8
  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."); }
9
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
10
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
11
9
  function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
12
10
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
11
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
12
+ 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."); }
13
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
14
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
15
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
16
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
13
17
  import { getInsightsAnonymousUserTokenInternal } from "../helpers/index.js";
14
- import { warning, noop, getAppIdAndApiKey, find } from "../lib/utils/index.js";
15
- export function createInsightsMiddleware(props) {
16
- var _ref = props || {},
17
- _insightsClient = _ref.insightsClient,
18
- insightsInitParams = _ref.insightsInitParams,
19
- onEvent = _ref.onEvent;
20
- if (_insightsClient !== null && !_insightsClient) {
21
- if (process.env.NODE_ENV === 'development') {
22
- throw new Error("The `insightsClient` option is required if you want userToken to be automatically set in search calls. If you don't want this behaviour, set it to `null`.");
23
- } else {
24
- throw new Error('The `insightsClient` option is required. To disable, set it to `null`.');
25
- }
18
+ import { warning, noop, getAppIdAndApiKey, find, safelyRunOnBrowser } from "../lib/utils/index.js";
19
+ var ALGOLIA_INSIGHTS_VERSION = '2.6.0';
20
+ var ALGOLIA_INSIGHTS_SRC = "https://cdn.jsdelivr.net/npm/search-insights@".concat(ALGOLIA_INSIGHTS_VERSION, "/dist/search-insights.min.js");
21
+ export function createInsightsMiddleware() {
22
+ var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
23
+ var _insightsClient = props.insightsClient,
24
+ insightsInitParams = props.insightsInitParams,
25
+ onEvent = props.onEvent,
26
+ _props$$$internal = props.$$internal,
27
+ $$internal = _props$$$internal === void 0 ? false : _props$$$internal;
28
+ var potentialInsightsClient = _insightsClient;
29
+ if (!_insightsClient && _insightsClient !== null) {
30
+ safelyRunOnBrowser(function (_ref) {
31
+ var window = _ref.window;
32
+ var pointer = window.AlgoliaAnalyticsObject || 'aa';
33
+ if (typeof pointer === 'string') {
34
+ potentialInsightsClient = window[pointer];
35
+ }
36
+ if (!potentialInsightsClient) {
37
+ window.AlgoliaAnalyticsObject = pointer;
38
+ if (!window[pointer]) {
39
+ window[pointer] = function () {
40
+ if (!window[pointer].queue) {
41
+ window[pointer].queue = [];
42
+ }
43
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
44
+ args[_key] = arguments[_key];
45
+ }
46
+ window[pointer].queue.push(args);
47
+ };
48
+ window[pointer].version = ALGOLIA_INSIGHTS_VERSION;
49
+ window[pointer].shouldAddScript = true;
50
+ }
51
+ potentialInsightsClient = window[pointer];
52
+ }
53
+ });
26
54
  }
27
- var hasInsightsClient = Boolean(_insightsClient);
28
- var insightsClient = _insightsClient === null ? noop : _insightsClient;
55
+ // if still no insightsClient was found, we use a noop
56
+ var insightsClient = potentialInsightsClient || noop;
29
57
  return function (_ref2) {
30
58
  var instantSearchInstance = _ref2.instantSearchInstance;
59
+ // remove existing default insights middleware
60
+ // user-provided insights middleware takes precedence
61
+ var existingInsightsMiddlewares = instantSearchInstance.middleware.filter(function (m) {
62
+ return m.instance.$$type === 'ais.insights' && m.instance.$$internal;
63
+ }).map(function (m) {
64
+ return m.creator;
65
+ });
66
+ instantSearchInstance.unuse.apply(instantSearchInstance, _toConsumableArray(existingInsightsMiddlewares));
31
67
  var _getAppIdAndApiKey = getAppIdAndApiKey(instantSearchInstance.client),
32
68
  _getAppIdAndApiKey2 = _slicedToArray(_getAppIdAndApiKey, 2),
33
69
  appId = _getAppIdAndApiKey2[0],
34
70
  apiKey = _getAppIdAndApiKey2[1];
35
71
 
36
72
  // search-insights.js also throws an error so dev-only clarification is sufficient
37
- if (process.env.NODE_ENV === 'development' && !(appId && apiKey)) {
38
- throw new Error('[insights middleware]: could not extract Algolia credentials from searchClient');
39
- }
73
+ process.env.NODE_ENV === 'development' ? warning(Boolean(appId && apiKey), 'could not extract Algolia credentials from searchClient in insights middleware.') : void 0;
40
74
  var queuedUserToken = undefined;
41
75
  var userTokenBeforeInit = undefined;
42
76
  if (Array.isArray(insightsClient.queue)) {
@@ -66,15 +100,39 @@ export function createInsightsMiddleware(props) {
66
100
  // Otherwise, the `init` call might override it with anonymous user token.
67
101
  userTokenBeforeInit = userToken;
68
102
  });
69
- insightsClient('init', _objectSpread({
70
- appId: appId,
71
- apiKey: apiKey
72
- }, insightsInitParams));
103
+
104
+ // Only `init` if the `insightsInitParams` option is passed or
105
+ // if the `insightsClient` version doesn't supports optional `init` calling.
106
+ if (insightsInitParams || !isModernInsightsClient(insightsClient)) {
107
+ insightsClient('init', _objectSpread({
108
+ appId: appId,
109
+ apiKey: apiKey,
110
+ partial: true
111
+ }, insightsInitParams));
112
+ }
73
113
  var initialParameters;
74
114
  var helper;
75
115
  return {
116
+ $$type: 'ais.insights',
117
+ $$internal: $$internal,
76
118
  onStateChange: function onStateChange() {},
77
- subscribe: function subscribe() {},
119
+ subscribe: function subscribe() {
120
+ if (!insightsClient.shouldAddScript) return;
121
+ var errorMessage = '[insights middleware]: could not load search-insights.js. Please load it manually following https://alg.li/insights-init';
122
+ try {
123
+ var script = document.createElement('script');
124
+ script.async = true;
125
+ script.src = ALGOLIA_INSIGHTS_SRC;
126
+ script.onerror = function () {
127
+ instantSearchInstance.emit('error', new Error(errorMessage));
128
+ };
129
+ document.body.appendChild(script);
130
+ insightsClient.shouldAddScript = false;
131
+ } catch (cause) {
132
+ insightsClient.shouldAddScript = false;
133
+ instantSearchInstance.emit('error', new Error(errorMessage));
134
+ }
135
+ },
78
136
  started: function started() {
79
137
  insightsClient('addAlgoliaAgent', 'insights-middleware');
80
138
  helper = instantSearchInstance.helper;
@@ -85,15 +143,23 @@ export function createInsightsMiddleware(props) {
85
143
  helper.overrideStateWithoutTriggeringChangeEvent(_objectSpread(_objectSpread({}, helper.state), {}, {
86
144
  clickAnalytics: true
87
145
  }));
88
- instantSearchInstance.scheduleSearch();
146
+ if (!$$internal) {
147
+ instantSearchInstance.scheduleSearch();
148
+ }
89
149
  var setUserTokenToSearch = function setUserTokenToSearch(userToken) {
150
+ if (!userToken) {
151
+ return;
152
+ }
153
+ var existingToken = helper.state.userToken;
90
154
  helper.overrideStateWithoutTriggeringChangeEvent(_objectSpread(_objectSpread({}, helper.state), {}, {
91
155
  userToken: userToken
92
156
  }));
93
- instantSearchInstance.scheduleSearch();
157
+ if (existingToken && existingToken !== userToken) {
158
+ instantSearchInstance.scheduleSearch();
159
+ }
94
160
  };
95
161
  var anonymousUserToken = getInsightsAnonymousUserTokenInternal();
96
- if (hasInsightsClient && anonymousUserToken) {
162
+ if (anonymousUserToken) {
97
163
  // When `aa('init', { ... })` is called, it creates an anonymous user token in cookie.
98
164
  // We can set it as userToken.
99
165
  setUserTokenToSearch(anonymousUserToken);
@@ -102,8 +168,10 @@ export function createInsightsMiddleware(props) {
102
168
  // We consider the `userToken` coming from a `init` call to have a higher
103
169
  // importance than the one coming from the queue.
104
170
  if (userTokenBeforeInit) {
171
+ setUserTokenToSearch(userTokenBeforeInit);
105
172
  insightsClient('setUserToken', userTokenBeforeInit);
106
173
  } else if (queuedUserToken) {
174
+ setUserTokenToSearch(queuedUserToken);
107
175
  insightsClient('setUserToken', queuedUserToken);
108
176
  }
109
177
 
@@ -111,16 +179,31 @@ export function createInsightsMiddleware(props) {
111
179
  insightsClient('onUserTokenChange', setUserTokenToSearch, {
112
180
  immediate: true
113
181
  });
182
+ var insightsClientWithLocalCredentials = insightsClient;
183
+ if (isModernInsightsClient(insightsClient)) {
184
+ insightsClientWithLocalCredentials = function insightsClientWithLocalCredentials(method, payload) {
185
+ var extraParams = {
186
+ headers: {
187
+ 'X-Algolia-Application-Id': appId,
188
+ 'X-Algolia-API-Key': apiKey
189
+ }
190
+ };
191
+
192
+ // @ts-ignore we are calling this only when we know that the client actually is correct
193
+ return insightsClient(method, payload, extraParams);
194
+ };
195
+ }
114
196
  instantSearchInstance.sendEventToInsights = function (event) {
115
197
  if (onEvent) {
116
- onEvent(event, _insightsClient);
198
+ onEvent(event, insightsClientWithLocalCredentials);
117
199
  } else if (event.insightsMethod) {
118
- var hasUserToken = Boolean(helper.state.userToken);
119
- if (hasUserToken) {
120
- insightsClient(event.insightsMethod, event.payload);
121
- } else {
122
- process.env.NODE_ENV === 'development' ? warning(false, "\nCannot send event to Algolia Insights because `userToken` is not set.\n\nSee documentation: https://www.algolia.com/doc/guides/building-search-ui/going-further/send-insights-events/js/#setting-the-usertoken\n") : void 0;
200
+ // Source is used to differentiate events sent by instantsearch from those sent manually.
201
+ event.payload.algoliaSource = ['instantsearch'];
202
+ if (event.eventModifier === 'internal') {
203
+ event.payload.algoliaSource.push('instantsearch-internal');
123
204
  }
205
+ insightsClientWithLocalCredentials(event.insightsMethod, event.payload);
206
+ process.env.NODE_ENV === 'development' ? warning(Boolean(helper.state.userToken), "\nCannot send event to Algolia Insights because `userToken` is not set.\n\nSee documentation: https://www.algolia.com/doc/guides/building-search-ui/going-further/send-insights-events/js/#setting-the-usertoken\n") : void 0;
124
207
  } else {
125
208
  process.env.NODE_ENV === 'development' ? warning(false, 'Cannot send event to Algolia Insights because `insightsMethod` option is missing.') : void 0;
126
209
  }
@@ -130,10 +213,29 @@ export function createInsightsMiddleware(props) {
130
213
  insightsClient('onUserTokenChange', undefined);
131
214
  instantSearchInstance.sendEventToInsights = noop;
132
215
  if (helper && initialParameters) {
133
- helper.setState(_objectSpread(_objectSpread({}, helper.state), initialParameters));
216
+ helper.overrideStateWithoutTriggeringChangeEvent(_objectSpread(_objectSpread({}, helper.state), initialParameters));
134
217
  instantSearchInstance.scheduleSearch();
135
218
  }
136
219
  }
137
220
  };
138
221
  };
222
+ }
223
+
224
+ /**
225
+ * Determines if a given insights `client` supports the optional call to `init`
226
+ * and the ability to set credentials via extra parameters when sending events.
227
+ */
228
+ function isModernInsightsClient(client) {
229
+ var _split$map = (client.version || '').split('.').map(Number),
230
+ _split$map2 = _slicedToArray(_split$map, 2),
231
+ major = _split$map2[0],
232
+ minor = _split$map2[1];
233
+
234
+ /* eslint-disable @typescript-eslint/naming-convention */
235
+ var v3 = major >= 3;
236
+ var v2_6 = major === 2 && minor >= 6;
237
+ var v1_10 = major === 1 && minor >= 10;
238
+ /* eslint-enable @typescript-eslint/naming-convention */
239
+
240
+ return v3 || v2_6 || v1_10;
139
241
  }
@@ -7,4 +7,6 @@ export declare function isMetadataEnabled(): boolean;
7
7
  * - widget name
8
8
  * - connector name
9
9
  */
10
- export declare function createMetadataMiddleware(): InternalMiddleware;
10
+ export declare function createMetadataMiddleware({ $$internal, }?: {
11
+ $$internal?: boolean;
12
+ }): InternalMiddleware;
@@ -1,5 +1,5 @@
1
1
  import { createInitArgs, safelyRunOnBrowser } from "../lib/utils/index.js";
2
- function extractPayload(widgets, instantSearchInstance, payload) {
2
+ function extractWidgetPayload(widgets, instantSearchInstance, payload) {
3
3
  var initOptions = createInitArgs(instantSearchInstance, instantSearchInstance.mainIndex, instantSearchInstance._initialUiState);
4
4
  widgets.forEach(function (widget) {
5
5
  var widgetParams = {};
@@ -21,7 +21,7 @@ function extractPayload(widgets, instantSearchInstance, payload) {
21
21
  params: params
22
22
  });
23
23
  if (widget.$$type === 'ais.index') {
24
- extractPayload(widget.getWidgets(), instantSearchInstance, payload);
24
+ extractWidgetPayload(widget.getWidgets(), instantSearchInstance, payload);
25
25
  }
26
26
  });
27
27
  }
@@ -45,8 +45,11 @@ export function isMetadataEnabled() {
45
45
  * - connector name
46
46
  */
47
47
  export function createMetadataMiddleware() {
48
- return function (_ref2) {
49
- var instantSearchInstance = _ref2.instantSearchInstance;
48
+ var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
49
+ _ref2$$$internal = _ref2.$$internal,
50
+ $$internal = _ref2$$$internal === void 0 ? false : _ref2$$$internal;
51
+ return function (_ref3) {
52
+ var instantSearchInstance = _ref3.instantSearchInstance;
50
53
  var payload = {
51
54
  widgets: []
52
55
  };
@@ -54,13 +57,22 @@ export function createMetadataMiddleware() {
54
57
  var refNode = document.querySelector('head');
55
58
  payloadContainer.name = 'instantsearch:widgets';
56
59
  return {
60
+ $$type: 'ais.metadata',
61
+ $$internal: $$internal,
57
62
  onStateChange: function onStateChange() {},
58
63
  subscribe: function subscribe() {
59
64
  // using setTimeout here to delay extraction until widgets have been added in a tick (e.g. Vue)
60
65
  setTimeout(function () {
61
66
  var client = instantSearchInstance.client;
62
67
  payload.ua = client.transporter && client.transporter.userAgent ? client.transporter.userAgent.value : client._ua;
63
- extractPayload(instantSearchInstance.mainIndex.getWidgets(), instantSearchInstance, payload);
68
+ extractWidgetPayload(instantSearchInstance.mainIndex.getWidgets(), instantSearchInstance, payload);
69
+ instantSearchInstance.middleware.forEach(function (middleware) {
70
+ return payload.widgets.push({
71
+ middleware: true,
72
+ type: middleware.instance.$$type,
73
+ internal: middleware.instance.$$internal
74
+ });
75
+ });
64
76
  payloadContainer.content = JSON.stringify(payload);
65
77
  refNode.appendChild(payloadContainer);
66
78
  }, 0);
@@ -12,7 +12,9 @@ export var createRouterMiddleware = function createRouterMiddleware() {
12
12
  var _props$router = props.router,
13
13
  router = _props$router === void 0 ? historyRouter() : _props$router,
14
14
  _props$stateMapping = props.stateMapping,
15
- stateMapping = _props$stateMapping === void 0 ? simpleStateMapping() : _props$stateMapping;
15
+ stateMapping = _props$stateMapping === void 0 ? simpleStateMapping() : _props$stateMapping,
16
+ _props$$$internal = props.$$internal,
17
+ $$internal = _props$$$internal === void 0 ? false : _props$$$internal;
16
18
  return function (_ref) {
17
19
  var instantSearchInstance = _ref.instantSearchInstance;
18
20
  function topLevelCreateURL(nextState) {
@@ -29,6 +31,8 @@ export var createRouterMiddleware = function createRouterMiddleware() {
29
31
  var lastRouteState = undefined;
30
32
  var initialUiState = instantSearchInstance._initialUiState;
31
33
  return {
34
+ $$type: "ais.router({router:".concat(router.$$type || '__unknown__', ", stateMapping:").concat(stateMapping.$$type || '__unknown__', "})"),
35
+ $$internal: $$internal,
32
36
  onStateChange: function onStateChange(_ref2) {
33
37
  var uiState = _ref2.uiState;
34
38
  var routeState = stateMapping.stateToRoute(uiState);
@@ -1,6 +1,24 @@
1
- import type { InsightsMethodMap, InsightsClient as _InsightsClient } from 'search-insights';
1
+ import type { Hit } from './results';
2
+ import type { InsightsMethodMap as _InsightsMethodMap, InsightsClient as _InsightsClient } from 'search-insights';
2
3
  export type { Init as InsightsInit, AddAlgoliaAgent as InsightsAddAlgoliaAgent, SetUserToken as InsightsSetUserToken, GetUserToken as InsightsGetUserToken, OnUserTokenChange as InsightsOnUserTokenChange, } from 'search-insights';
4
+ export type InsightsMethodMap = _InsightsMethodMap;
3
5
  export type InsightsClientMethod = keyof InsightsMethodMap;
6
+ /**
7
+ * Method allowed by the insights middleware.
8
+ */
9
+ export type InsightsMethod = 'clickedObjectIDsAfterSearch' | 'clickedObjectIDs' | 'clickedFilters' | 'convertedObjectIDsAfterSearch' | 'convertedObjectIDs' | 'convertedFilters' | 'viewedObjectIDs' | 'viewedFilters';
10
+ /**
11
+ * The event sent to the insights middleware.
12
+ */
13
+ export type InsightsEvent<TMethod extends InsightsMethod = InsightsMethod> = {
14
+ insightsMethod?: TMethod;
15
+ payload: InsightsMethodMap[TMethod][0];
16
+ widgetType: string;
17
+ eventType: string;
18
+ eventModifier?: string;
19
+ hits?: Hit[];
20
+ attribute?: string;
21
+ };
4
22
  export type InsightsClientPayload = {
5
23
  eventName: string;
6
24
  queryID: string;
@@ -2,11 +2,27 @@ import type InstantSearch from '../lib/InstantSearch';
2
2
  import type { UiState } from './ui-state';
3
3
  import type { AtLeastOne } from './utils';
4
4
  export type MiddlewareDefinition<TUiState extends UiState = UiState> = {
5
+ /**
6
+ * string to identify the middleware
7
+ */
8
+ $$type: string;
9
+ /**
10
+ * Change handler called on every UiState change
11
+ */
5
12
  onStateChange(options: {
6
13
  uiState: TUiState;
7
14
  }): void;
15
+ /**
16
+ * Called when the middleware is added to InstantSearch
17
+ */
8
18
  subscribe(): void;
19
+ /**
20
+ * Called when InstantSearch is started
21
+ */
9
22
  started(): void;
23
+ /**
24
+ * Called when the middleware is removed from InstantSearch
25
+ */
10
26
  unsubscribe(): void;
11
27
  };
12
28
  export type MiddlewareOptions = {
@@ -34,6 +34,10 @@ export type Router<TRouteState = UiState> = {
34
34
  * Called when InstantSearch is started.
35
35
  */
36
36
  start?: () => void;
37
+ /**
38
+ * Identifier for this router. Used to differentiate between routers.
39
+ */
40
+ $$type?: string;
37
41
  };
38
42
  /**
39
43
  * The state mapping is a way to customize the structure before sending it to the router.
@@ -55,4 +59,8 @@ export type StateMapping<TUiState = UiState, TRouteState = TUiState> = {
55
59
  * The format is the output of `stateToRoute`.
56
60
  */
57
61
  routeToState(routeState: TRouteState): TUiState;
62
+ /**
63
+ * Identifier for this stateMapping. Used to differentiate between stateMappings.
64
+ */
65
+ $$type?: string;
58
66
  };
@@ -8,7 +8,7 @@ import { cx } from '@algolia/ui-components-shared';
8
8
  import { h, render } from 'preact';
9
9
  import Hits from "../../components/Hits/Hits.js";
10
10
  import connectHits from "../../connectors/hits/connectHits.js";
11
- import { withInsights, withInsightsListener } from "../../lib/insights/index.js";
11
+ import { withInsights } from "../../lib/insights/index.js";
12
12
  import { component } from "../../lib/suit.js";
13
13
  import { prepareTemplateProps } from "../../lib/templating/index.js";
14
14
  import { getContainerNode, createDocumentationMessageGenerator } from "../../lib/utils/index.js";
@@ -17,7 +17,6 @@ var withUsage = createDocumentationMessageGenerator({
17
17
  name: 'hits'
18
18
  });
19
19
  var suit = component('Hits');
20
- var HitsWithInsightsListener = withInsightsListener(Hits);
21
20
  var renderer = function renderer(_ref) {
22
21
  var renderState = _ref.renderState,
23
22
  cssClasses = _ref.cssClasses,
@@ -38,7 +37,7 @@ var renderer = function renderer(_ref) {
38
37
  });
39
38
  return;
40
39
  }
41
- render(h(HitsWithInsightsListener, {
40
+ render(h(Hits, {
42
41
  cssClasses: cssClasses,
43
42
  hits: receivedHits,
44
43
  results: results,
@@ -8,7 +8,7 @@ import { cx } from '@algolia/ui-components-shared';
8
8
  import { h, render } from 'preact';
9
9
  import InfiniteHits from "../../components/InfiniteHits/InfiniteHits.js";
10
10
  import connectInfiniteHits from "../../connectors/infinite-hits/connectInfiniteHits.js";
11
- import { withInsights, withInsightsListener } from "../../lib/insights/index.js";
11
+ import { withInsights } from "../../lib/insights/index.js";
12
12
  import { component } from "../../lib/suit.js";
13
13
  import { prepareTemplateProps } from "../../lib/templating/index.js";
14
14
  import { getContainerNode, createDocumentationMessageGenerator } from "../../lib/utils/index.js";
@@ -17,7 +17,6 @@ var withUsage = createDocumentationMessageGenerator({
17
17
  name: 'infinite-hits'
18
18
  });
19
19
  var suit = component('InfiniteHits');
20
- var InfiniteHitsWithInsightsListener = withInsightsListener(InfiniteHits);
21
20
  var renderer = function renderer(_ref) {
22
21
  var containerNode = _ref.containerNode,
23
22
  cssClasses = _ref.cssClasses,
@@ -43,7 +42,7 @@ var renderer = function renderer(_ref) {
43
42
  });
44
43
  return;
45
44
  }
46
- render(h(InfiniteHitsWithInsightsListener, {
45
+ render(h(InfiniteHits, {
47
46
  cssClasses: cssClasses,
48
47
  hits: hits,
49
48
  results: results,
@@ -1,6 +1,6 @@
1
1
 
2
2
  import type { PaginationConnectorParams, PaginationWidgetDescription } from '../../connectors/pagination/connectPagination';
3
- import type { WidgetFactory } from '../../types';
3
+ import type { Template, WidgetFactory } from '../../types';
4
4
  export type PaginationCSSClasses = Partial<{
5
5
  /**
6
6
  * CSS classes added to the root element of the widget.
@@ -55,19 +55,26 @@ export type PaginationTemplates = Partial<{
55
55
  /**
56
56
  * Label for the Previous link.
57
57
  */
58
- previous: string;
58
+ previous: Template;
59
59
  /**
60
60
  * Label for the Next link.
61
61
  */
62
- next: string;
62
+ next: Template;
63
+ /**
64
+ * Label for the link of a certain page
65
+ * Page is one-based, so `page` will be `1` for the first page.
66
+ */
67
+ page: Template<{
68
+ page: number;
69
+ }>;
63
70
  /**
64
71
  * Label for the First link.
65
72
  */
66
- first: string;
73
+ first: Template;
67
74
  /**
68
75
  * Label for the Last link.
69
76
  */
70
- last: string;
77
+ last: Template;
71
78
  }>;
72
79
  export type PaginationWidgetParams = {
73
80
  /**
@@ -15,28 +15,40 @@ var withUsage = createDocumentationMessageGenerator({
15
15
  name: 'pagination'
16
16
  });
17
17
  var defaultTemplates = {
18
- previous: '‹',
19
- next: '',
20
- first: '«',
21
- last: '»'
18
+ previous: function previous() {
19
+ return '';
20
+ },
21
+ next: function next() {
22
+ return '›';
23
+ },
24
+ page: function page(_ref) {
25
+ var _page = _ref.page;
26
+ return "".concat(_page);
27
+ },
28
+ first: function first() {
29
+ return '«';
30
+ },
31
+ last: function last() {
32
+ return '»';
33
+ }
22
34
  };
23
- var renderer = function renderer(_ref) {
24
- var containerNode = _ref.containerNode,
25
- cssClasses = _ref.cssClasses,
26
- templates = _ref.templates,
27
- showFirst = _ref.showFirst,
28
- showLast = _ref.showLast,
29
- showPrevious = _ref.showPrevious,
30
- showNext = _ref.showNext,
31
- scrollToNode = _ref.scrollToNode;
32
- return function (_ref2, isFirstRendering) {
33
- var createURL = _ref2.createURL,
34
- currentRefinement = _ref2.currentRefinement,
35
- nbPages = _ref2.nbPages,
36
- pages = _ref2.pages,
37
- isFirstPage = _ref2.isFirstPage,
38
- isLastPage = _ref2.isLastPage,
39
- refine = _ref2.refine;
35
+ var renderer = function renderer(_ref2) {
36
+ var containerNode = _ref2.containerNode,
37
+ cssClasses = _ref2.cssClasses,
38
+ templates = _ref2.templates,
39
+ showFirst = _ref2.showFirst,
40
+ showLast = _ref2.showLast,
41
+ showPrevious = _ref2.showPrevious,
42
+ showNext = _ref2.showNext,
43
+ scrollToNode = _ref2.scrollToNode;
44
+ return function (_ref3, isFirstRendering) {
45
+ var createURL = _ref3.createURL,
46
+ currentRefinement = _ref3.currentRefinement,
47
+ nbPages = _ref3.nbPages,
48
+ pages = _ref3.pages,
49
+ isFirstPage = _ref3.isFirstPage,
50
+ isLastPage = _ref3.isLastPage,
51
+ refine = _ref3.refine;
40
52
  if (isFirstRendering) return;
41
53
  var setCurrentPage = function setCurrentPage(pageNumber) {
42
54
  refine(pageNumber);
@@ -62,24 +74,24 @@ var renderer = function renderer(_ref) {
62
74
  };
63
75
  };
64
76
  var pagination = function pagination(widgetParams) {
65
- var _ref3 = widgetParams || {},
66
- container = _ref3.container,
67
- _ref3$templates = _ref3.templates,
68
- userTemplates = _ref3$templates === void 0 ? {} : _ref3$templates,
69
- _ref3$cssClasses = _ref3.cssClasses,
70
- userCssClasses = _ref3$cssClasses === void 0 ? {} : _ref3$cssClasses,
71
- totalPages = _ref3.totalPages,
72
- padding = _ref3.padding,
73
- _ref3$showFirst = _ref3.showFirst,
74
- showFirst = _ref3$showFirst === void 0 ? true : _ref3$showFirst,
75
- _ref3$showLast = _ref3.showLast,
76
- showLast = _ref3$showLast === void 0 ? true : _ref3$showLast,
77
- _ref3$showPrevious = _ref3.showPrevious,
78
- showPrevious = _ref3$showPrevious === void 0 ? true : _ref3$showPrevious,
79
- _ref3$showNext = _ref3.showNext,
80
- showNext = _ref3$showNext === void 0 ? true : _ref3$showNext,
81
- _ref3$scrollTo = _ref3.scrollTo,
82
- userScrollTo = _ref3$scrollTo === void 0 ? 'body' : _ref3$scrollTo;
77
+ var _ref4 = widgetParams || {},
78
+ container = _ref4.container,
79
+ _ref4$templates = _ref4.templates,
80
+ userTemplates = _ref4$templates === void 0 ? {} : _ref4$templates,
81
+ _ref4$cssClasses = _ref4.cssClasses,
82
+ userCssClasses = _ref4$cssClasses === void 0 ? {} : _ref4$cssClasses,
83
+ totalPages = _ref4.totalPages,
84
+ padding = _ref4.padding,
85
+ _ref4$showFirst = _ref4.showFirst,
86
+ showFirst = _ref4$showFirst === void 0 ? true : _ref4$showFirst,
87
+ _ref4$showLast = _ref4.showLast,
88
+ showLast = _ref4$showLast === void 0 ? true : _ref4$showLast,
89
+ _ref4$showPrevious = _ref4.showPrevious,
90
+ showPrevious = _ref4$showPrevious === void 0 ? true : _ref4$showPrevious,
91
+ _ref4$showNext = _ref4.showNext,
92
+ showNext = _ref4$showNext === void 0 ? true : _ref4$showNext,
93
+ _ref4$scrollTo = _ref4.scrollTo,
94
+ userScrollTo = _ref4$scrollTo === void 0 ? 'body' : _ref4$scrollTo;
83
95
  if (!container) {
84
96
  throw new Error(withUsage('The `container` option is required.'));
85
97
  }
@@ -90,8 +90,6 @@ var panel = function panel(panelWidgetParams) {
90
90
  }
91
91
  var containerNode = getContainerNode(widgetParams.container);
92
92
  var defaultTemplates = {
93
- header: '',
94
- footer: '',
95
93
  collapseButtonText: function collapseButtonText(_ref4) {
96
94
  var isCollapsed = _ref4.collapsed;
97
95
  return "<svg\n class=\"".concat(cssClasses.collapseIcon, "\"\n style=\"width: 1em; height: 1em;\"\n viewBox=\"0 0 500 500\"\n >\n <path d=\"").concat(isCollapsed ? 'M100 250l300-150v300z' : 'M250 400l150-300H100z', "\" fill=\"currentColor\" />\n </svg>");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instantsearch.js",
3
- "version": "4.54.0",
3
+ "version": "4.55.0",
4
4
  "description": "InstantSearch.js is a JavaScript library for building performant and instant search experiences with Algolia.",
5
5
  "homepage": "https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/js/",
6
6
  "types": "es/index.d.ts",
@@ -38,7 +38,7 @@
38
38
  "htm": "^3.0.0",
39
39
  "preact": "^10.10.0",
40
40
  "qs": "^6.5.1 < 6.10",
41
- "search-insights": "^2.1.0"
41
+ "search-insights": "^2.6.0"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "algoliasearch": ">= 3.1 < 6"
@@ -55,9 +55,9 @@
55
55
  "version": "./scripts/version/update-version.js"
56
56
  },
57
57
  "devDependencies": {
58
- "@instantsearch/mocks": "1.10.0",
59
- "@instantsearch/tests": "1.10.0",
60
- "@instantsearch/testutils": "1.0.13",
58
+ "@instantsearch/mocks": "1.12.0",
59
+ "@instantsearch/tests": "1.12.0",
60
+ "@instantsearch/testutils": "1.1.0",
61
61
  "@storybook/html": "5.3.9",
62
62
  "@types/scriptjs": "0.0.2",
63
63
  "algoliasearch": "4.14.3",
@@ -65,5 +65,5 @@
65
65
  "scriptjs": "2.5.9",
66
66
  "webpack": "4.41.5"
67
67
  },
68
- "gitHead": "419aa9869727dceeb49dfc5289a0b9241e0e5827"
68
+ "gitHead": "c483ae31e1e615be61dffb5d0bc04a4927960a67"
69
69
  }