instantsearch.js 4.57.0 → 4.59.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 (40) hide show
  1. package/README.md +1 -2
  2. package/cjs/components/Pagination/Pagination.js +4 -4
  3. package/cjs/components/RefinementList/RefinementList.js +2 -1
  4. package/cjs/components/SearchBox/SearchBox.js +5 -2
  5. package/cjs/components/Selector/Selector.js +4 -2
  6. package/cjs/components/Slider/Slider.js +3 -1
  7. package/cjs/lib/InstantSearch.js +44 -7
  8. package/cjs/lib/utils/createSendEventForFacet.js +12 -5
  9. package/cjs/lib/utils/createSendEventForHits.js +12 -6
  10. package/cjs/lib/version.js +1 -1
  11. package/cjs/middlewares/createInsightsMiddleware.js +16 -5
  12. package/cjs/widgets/index/index.js +16 -7
  13. package/cjs/widgets/sort-by/sort-by.js +2 -1
  14. package/dist/instantsearch.development.d.ts +17 -3
  15. package/dist/instantsearch.development.js +125 -56
  16. package/dist/instantsearch.development.js.map +1 -1
  17. package/dist/instantsearch.production.d.ts +17 -3
  18. package/dist/instantsearch.production.min.d.ts +17 -3
  19. package/dist/instantsearch.production.min.js +2 -2
  20. package/dist/instantsearch.production.min.js.map +1 -1
  21. package/es/components/InternalHighlight/InternalHighlight.d.ts +1 -1
  22. package/es/components/Pagination/Pagination.js +4 -4
  23. package/es/components/RefinementList/RefinementList.js +2 -1
  24. package/es/components/SearchBox/SearchBox.d.ts +3 -0
  25. package/es/components/SearchBox/SearchBox.js +5 -2
  26. package/es/components/Selector/Selector.d.ts +2 -1
  27. package/es/components/Selector/Selector.js +4 -2
  28. package/es/components/Slider/Slider.js +3 -1
  29. package/es/lib/InstantSearch.d.ts +15 -0
  30. package/es/lib/InstantSearch.js +42 -6
  31. package/es/lib/utils/createSendEventForFacet.d.ts +1 -1
  32. package/es/lib/utils/createSendEventForFacet.js +12 -5
  33. package/es/lib/utils/createSendEventForHits.d.ts +2 -2
  34. package/es/lib/utils/createSendEventForHits.js +12 -6
  35. package/es/lib/version.d.ts +1 -1
  36. package/es/lib/version.js +1 -1
  37. package/es/middlewares/createInsightsMiddleware.js +16 -5
  38. package/es/widgets/index/index.js +16 -7
  39. package/es/widgets/sort-by/sort-by.js +2 -1
  40. package/package.json +8 -8
@@ -1 +1 @@
1
- export declare const InternalHighlight: ({ parts, highlightedTagName, nonHighlightedTagName, separator, className, classNames, ...props }: import("@algolia/ui-components-highlight-vdom").HighlightProps) => JSX.Element;
1
+ export declare const InternalHighlight: (userProps: import("@algolia/ui-components-highlight-vdom").HighlightProps) => JSX.Element;
@@ -19,7 +19,7 @@ function Pagination(props) {
19
19
  }, h("ul", {
20
20
  className: props.cssClasses.list
21
21
  }, props.showFirst && h(PaginationLink, {
22
- ariaLabel: "First",
22
+ ariaLabel: "First Page",
23
23
  className: props.cssClasses.firstPageItem,
24
24
  isDisabled: props.isFirstPage,
25
25
  templates: props.templates,
@@ -29,7 +29,7 @@ function Pagination(props) {
29
29
  cssClasses: props.cssClasses,
30
30
  createClickHandler: createClickHandler
31
31
  }), props.showPrevious && h(PaginationLink, {
32
- ariaLabel: "Previous",
32
+ ariaLabel: "Previous Page",
33
33
  className: props.cssClasses.previousPageItem,
34
34
  isDisabled: props.isFirstPage,
35
35
  templates: props.templates,
@@ -52,7 +52,7 @@ function Pagination(props) {
52
52
  createClickHandler: createClickHandler
53
53
  });
54
54
  }), props.showNext && h(PaginationLink, {
55
- ariaLabel: "Next",
55
+ ariaLabel: "Next Page",
56
56
  className: props.cssClasses.nextPageItem,
57
57
  isDisabled: props.isLastPage,
58
58
  templates: props.templates,
@@ -62,7 +62,7 @@ function Pagination(props) {
62
62
  cssClasses: props.cssClasses,
63
63
  createClickHandler: createClickHandler
64
64
  }), props.showLast && h(PaginationLink, {
65
- ariaLabel: "Last",
65
+ ariaLabel: "Last Page, Page ".concat(props.nbPages),
66
66
  className: props.cssClasses.lastPageItem,
67
67
  isDisabled: props.isLastPage,
68
68
  templates: props.templates,
@@ -203,7 +203,8 @@ var RefinementList = /*#__PURE__*/function (_Component) {
203
203
  // This sets the search box to a controlled state because
204
204
  // we don't rely on the `refine` prop but on `onChange`.
205
205
  ,
206
- searchAsYouType: false
206
+ searchAsYouType: false,
207
+ ariaLabel: "Search for filters"
207
208
  }));
208
209
  var facetValues = this.props.facetValues && this.props.facetValues.length > 0 && h("ul", {
209
210
  className: this.props.cssClasses.list
@@ -18,6 +18,7 @@ type SearchBoxProps = {
18
18
  searchAsYouType?: boolean;
19
19
  isSearchStalled?: boolean;
20
20
  disabled?: boolean;
21
+ ariaLabel?: string;
21
22
  onChange?: (event: Event) => void;
22
23
  onSubmit?: (event: Event) => void;
23
24
  onReset?: (event: Event) => void;
@@ -31,6 +32,7 @@ declare const defaultProps: {
31
32
  searchAsYouType: boolean;
32
33
  isSearchStalled: boolean;
33
34
  disabled: boolean;
35
+ ariaLabel: string;
34
36
  onChange: typeof noop;
35
37
  onSubmit: typeof noop;
36
38
  onReset: typeof noop;
@@ -51,6 +53,7 @@ declare class SearchBox extends Component<SearchBoxPropsWithDefaultProps, Search
51
53
  searchAsYouType: boolean;
52
54
  isSearchStalled: boolean;
53
55
  disabled: boolean;
56
+ ariaLabel: string;
54
57
  onChange: typeof noop;
55
58
  onSubmit: typeof noop;
56
59
  onReset: typeof noop;
@@ -24,6 +24,7 @@ var defaultProps = {
24
24
  searchAsYouType: true,
25
25
  isSearchStalled: false,
26
26
  disabled: false,
27
+ ariaLabel: 'Search',
27
28
  onChange: noop,
28
29
  onSubmit: noop,
29
30
  onReset: noop,
@@ -140,7 +141,8 @@ var SearchBox = /*#__PURE__*/function (_Component) {
140
141
  showReset = _this$props4.showReset,
141
142
  showLoadingIndicator = _this$props4.showLoadingIndicator,
142
143
  templates = _this$props4.templates,
143
- isSearchStalled = _this$props4.isSearchStalled;
144
+ isSearchStalled = _this$props4.isSearchStalled,
145
+ ariaLabel = _this$props4.ariaLabel;
144
146
  return h("div", {
145
147
  className: cssClasses.root
146
148
  }, h("form", {
@@ -167,7 +169,8 @@ var SearchBox = /*#__PURE__*/function (_Component) {
167
169
  maxLength: 512,
168
170
  onInput: this.onInput,
169
171
  onBlur: this.onBlur,
170
- onFocus: this.onFocus
172
+ onFocus: this.onFocus,
173
+ "aria-label": ariaLabel
171
174
  }), h(Template, {
172
175
  templateKey: "submit",
173
176
  rootTagName: "button",
@@ -14,6 +14,7 @@ export type SelectorProps = {
14
14
  currentValue?: string | number;
15
15
  options: SelectorOption[];
16
16
  setValue: (value: string) => void;
17
+ ariaLabel?: string;
17
18
  };
18
- declare function Selector({ currentValue, options, cssClasses, setValue, }: SelectorProps): h.JSX.Element;
19
+ declare function Selector({ currentValue, options, cssClasses, setValue, ariaLabel, }: SelectorProps): h.JSX.Element;
19
20
  export default Selector;
@@ -4,13 +4,15 @@ function Selector(_ref) {
4
4
  var currentValue = _ref.currentValue,
5
5
  options = _ref.options,
6
6
  cssClasses = _ref.cssClasses,
7
- setValue = _ref.setValue;
7
+ setValue = _ref.setValue,
8
+ ariaLabel = _ref.ariaLabel;
8
9
  return h("select", {
9
10
  className: cx(cssClasses.select),
10
11
  onChange: function onChange(event) {
11
12
  return setValue(event.target.value);
12
13
  },
13
- value: "".concat(currentValue)
14
+ value: "".concat(currentValue),
15
+ "aria-label": ariaLabel
14
16
  }, options.map(function (option) {
15
17
  return h("option", {
16
18
  className: cx(cssClasses.option),
@@ -49,8 +49,10 @@ var Slider = /*#__PURE__*/function (_Component) {
49
49
  parseFloat(props['aria-valuenow']) * 100) / 100;
50
50
  var value = _typeof(tooltips) === 'object' && tooltips.format ? tooltips.format(roundedValue) : roundedValue;
51
51
  var className = cx(props.className, props['data-handle-key'] === 0 && 'rheostat-handle-lower', props['data-handle-key'] === 1 && 'rheostat-handle-upper');
52
+ var ariaLabel = props['data-handle-key'] === 0 ? 'Minimum Filter Handle' : 'Maximum Filter Handle';
52
53
  return h("div", _extends({}, props, {
53
- className: className
54
+ className: className,
55
+ "aria-label": ariaLabel
54
56
  }), tooltips && h("div", {
55
57
  className: "rheostat-tooltip"
56
58
  }, value));
@@ -96,8 +96,21 @@ export type InstantSearchOptions<TUiState extends UiState = UiState, TRouteState
96
96
  * @deprecated This property will be still supported in 4.x releases, but not further. It is replaced by the `insights` middleware. For more information, visit https://www.algolia.com/doc/guides/getting-insights-and-analytics/search-analytics/click-through-and-conversions/how-to/send-click-and-conversion-events-with-instantsearch/js/
97
97
  */
98
98
  insightsClient?: AlgoliaInsightsClient;
99
+ future?: {
100
+ /**
101
+ * Changes the way `dispose` is used in InstantSearch lifecycle.
102
+ *
103
+ * If `false` (by default), each widget unmounting will remove its state as well, even if there are multiple widgets reading that UI State.
104
+ *
105
+ * If `true`, each widget unmounting will only remove its own state if it's the last of its type. This allows for dynamically adding and removing widgets without losing their state.
106
+ *
107
+ * @default false
108
+ */
109
+ preserveSharedStateOnUnmount?: boolean;
110
+ };
99
111
  };
100
112
  export type InstantSearchStatus = 'idle' | 'loading' | 'stalled' | 'error';
113
+ export declare const INSTANTSEARCH_FUTURE_DEFAULTS: Required<InstantSearchOptions['future']>;
101
114
  /**
102
115
  * The actual implementation of the InstantSearch. This is
103
116
  * created using the `instantsearch` factory function.
@@ -108,6 +121,7 @@ declare class InstantSearch<TUiState extends UiState = UiState, TRouteState = TU
108
121
  indexName: string;
109
122
  insightsClient: AlgoliaInsightsClient | null;
110
123
  onStateChange: InstantSearchOptions<TUiState>['onStateChange'] | null;
124
+ future: NonNullable<InstantSearchOptions<TUiState>['future']>;
111
125
  helper: AlgoliaSearchHelper | null;
112
126
  mainHelper: AlgoliaSearchHelper | null;
113
127
  mainIndex: IndexWidget;
@@ -121,6 +135,7 @@ declare class InstantSearch<TUiState extends UiState = UiState, TRouteState = TU
121
135
  _createURL: CreateURL<TUiState>;
122
136
  _searchFunction?: InstantSearchOptions['searchFunction'];
123
137
  _mainHelperSearch?: AlgoliaSearchHelper['search'];
138
+ _insights: InstantSearchOptions['insights'];
124
139
  middleware: Array<{
125
140
  creator: Middleware<TUiState>;
126
141
  instance: MiddlewareDefinition<TUiState>;
@@ -36,6 +36,10 @@ function defaultCreateURL() {
36
36
  /**
37
37
  * Global options for an InstantSearch instance.
38
38
  */
39
+ export var INSTANTSEARCH_FUTURE_DEFAULTS = {
40
+ preserveSharedStateOnUnmount: false
41
+ };
42
+
39
43
  /**
40
44
  * The actual implementation of the InstantSearch. This is
41
45
  * created using the `instantsearch` factory function.
@@ -45,6 +49,7 @@ var InstantSearch = /*#__PURE__*/function (_EventEmitter) {
45
49
  _inherits(InstantSearch, _EventEmitter);
46
50
  var _super = _createSuper(InstantSearch);
47
51
  function InstantSearch(options) {
52
+ var _options$future2;
48
53
  var _this;
49
54
  _classCallCheck(this, InstantSearch);
50
55
  _this = _super.call(this);
@@ -54,6 +59,7 @@ var InstantSearch = /*#__PURE__*/function (_EventEmitter) {
54
59
  _defineProperty(_assertThisInitialized(_this), "indexName", void 0);
55
60
  _defineProperty(_assertThisInitialized(_this), "insightsClient", void 0);
56
61
  _defineProperty(_assertThisInitialized(_this), "onStateChange", null);
62
+ _defineProperty(_assertThisInitialized(_this), "future", void 0);
57
63
  _defineProperty(_assertThisInitialized(_this), "helper", void 0);
58
64
  _defineProperty(_assertThisInitialized(_this), "mainHelper", void 0);
59
65
  _defineProperty(_assertThisInitialized(_this), "mainIndex", void 0);
@@ -67,6 +73,7 @@ var InstantSearch = /*#__PURE__*/function (_EventEmitter) {
67
73
  _defineProperty(_assertThisInitialized(_this), "_createURL", void 0);
68
74
  _defineProperty(_assertThisInitialized(_this), "_searchFunction", void 0);
69
75
  _defineProperty(_assertThisInitialized(_this), "_mainHelperSearch", void 0);
76
+ _defineProperty(_assertThisInitialized(_this), "_insights", void 0);
70
77
  _defineProperty(_assertThisInitialized(_this), "middleware", []);
71
78
  _defineProperty(_assertThisInitialized(_this), "sendEventToInsights", void 0);
72
79
  /**
@@ -117,7 +124,7 @@ var InstantSearch = /*#__PURE__*/function (_EventEmitter) {
117
124
  _options$routing = options.routing,
118
125
  routing = _options$routing === void 0 ? null : _options$routing,
119
126
  _options$insights = options.insights,
120
- insights = _options$insights === void 0 ? false : _options$insights,
127
+ insights = _options$insights === void 0 ? undefined : _options$insights,
121
128
  searchFunction = options.searchFunction,
122
129
  _options$stalledSearc = options.stalledSearchDelay,
123
130
  stalledSearchDelay = _options$stalledSearc === void 0 ? 200 : _options$stalledSearc,
@@ -126,7 +133,9 @@ var InstantSearch = /*#__PURE__*/function (_EventEmitter) {
126
133
  _options$insightsClie = options.insightsClient,
127
134
  insightsClient = _options$insightsClie === void 0 ? null : _options$insightsClie,
128
135
  _options$onStateChang = options.onStateChange,
129
- onStateChange = _options$onStateChang === void 0 ? null : _options$onStateChang;
136
+ onStateChange = _options$onStateChang === void 0 ? null : _options$onStateChang,
137
+ _options$future = options.future,
138
+ future = _options$future === void 0 ? _objectSpread(_objectSpread({}, INSTANTSEARCH_FUTURE_DEFAULTS), options.future || {}) : _options$future;
130
139
  if (searchClient === null) {
131
140
  throw new Error(withUsage('The `searchClient` option is required.'));
132
141
  }
@@ -143,7 +152,14 @@ var InstantSearch = /*#__PURE__*/function (_EventEmitter) {
143
152
  process.env.NODE_ENV === 'development' ? warning(!options.searchParameters, "The `searchParameters` option is deprecated and will not be supported in InstantSearch.js 4.x.\n\nYou can replace it with the `configure` widget:\n\n```\nsearch.addWidgets([\n configure(".concat(JSON.stringify(options.searchParameters, null, 2), ")\n]);\n```\n\nSee ").concat(createDocumentationLink({
144
153
  name: 'configure'
145
154
  }))) : void 0;
155
+ if (process.env.NODE_ENV === 'development' && ((_options$future2 = options.future) === null || _options$future2 === void 0 ? void 0 : _options$future2.preserveSharedStateOnUnmount) === undefined) {
156
+ // eslint-disable-next-line no-console
157
+ console.info("Starting from the next major version, InstantSearch will change how widgets state is preserved when they are removed. InstantSearch will keep the state of unmounted widgets to be usable by other widgets with the same attribute.\n\nWe recommend setting `future.preserveSharedStateOnUnmount` to true to adopt this change today.\nTo stay with the current behaviour and remove this warning, set the option to false.\n\nSee documentation: ".concat(createDocumentationLink({
158
+ name: 'instantsearch'
159
+ }), "#widget-param-future\n "));
160
+ }
146
161
  _this.client = searchClient;
162
+ _this.future = future;
147
163
  _this.insightsClient = insightsClient;
148
164
  _this.indexName = indexName;
149
165
  _this.helper = null;
@@ -164,6 +180,7 @@ var InstantSearch = /*#__PURE__*/function (_EventEmitter) {
164
180
  _this._createURL = defaultCreateURL;
165
181
  _this._initialUiState = initialUiState;
166
182
  _this._initialResults = null;
183
+ _this._insights = insights;
167
184
  if (searchFunction) {
168
185
  process.env.NODE_ENV === 'development' ? warning(false, "The `searchFunction` option is deprecated. Use `onStateChange` instead.") : void 0;
169
186
  _this._searchFunction = searchFunction;
@@ -175,8 +192,9 @@ var InstantSearch = /*#__PURE__*/function (_EventEmitter) {
175
192
  _this.use(createRouterMiddleware(routerOptions));
176
193
  }
177
194
 
178
- // This is the default middleware,
179
- // any user-provided middleware will be added later and override this one.
195
+ // This is the default Insights middleware,
196
+ // added when `insights` is set to true by the user.
197
+ // Any user-provided middleware will be added later and override this one.
180
198
  if (insights) {
181
199
  var insightsOptions = typeof insights === 'boolean' ? {} : insights;
182
200
  insightsOptions.$$internal = true;
@@ -468,6 +486,24 @@ var InstantSearch = /*#__PURE__*/function (_EventEmitter) {
468
486
  var instance = _ref6.instance;
469
487
  instance.started();
470
488
  });
489
+
490
+ // This is the automatic Insights middleware,
491
+ // added when `insights` is unset and the initial results possess `queryID`.
492
+ // Any user-provided middleware will be added later and override this one.
493
+ if (typeof this._insights === 'undefined') {
494
+ mainHelper.derivedHelpers[0].once('result', function () {
495
+ var hasAutomaticInsights = _this3.mainIndex.getScopedResults().some(function (_ref7) {
496
+ var results = _ref7.results;
497
+ return results === null || results === void 0 ? void 0 : results._automaticInsights;
498
+ });
499
+ if (hasAutomaticInsights) {
500
+ _this3.use(createInsightsMiddleware({
501
+ $$internal: true,
502
+ $$automatic: true
503
+ }));
504
+ }
505
+ });
506
+ }
471
507
  }
472
508
 
473
509
  /**
@@ -497,8 +533,8 @@ var InstantSearch = /*#__PURE__*/function (_EventEmitter) {
497
533
  (_this$mainHelper2 = this.mainHelper) === null || _this$mainHelper2 === void 0 ? void 0 : _this$mainHelper2.removeAllListeners();
498
534
  this.mainHelper = null;
499
535
  this.helper = null;
500
- this.middleware.forEach(function (_ref7) {
501
- var instance = _ref7.instance;
536
+ this.middleware.forEach(function (_ref8) {
537
+ var instance = _ref8.instance;
502
538
  instance.unsubscribe();
503
539
  });
504
540
  }
@@ -1,6 +1,6 @@
1
1
  import type { InstantSearch } from '../../types';
2
2
  import type { AlgoliaSearchHelper } from 'algoliasearch-helper';
3
- type BuiltInSendEventForFacet = (eventType: string, facetValue: string, eventName?: string) => void;
3
+ type BuiltInSendEventForFacet = (eventType: string, facetValue: string, eventName?: string, additionalData?: Record<string, any>) => void;
4
4
  type CustomSendEventForFacet = (customPayload: any) => void;
5
5
  export type SendEventForFacet = BuiltInSendEventForFacet & CustomSendEventForFacet;
6
6
  type CreateSendEventForFacetOptions = {
@@ -1,3 +1,8 @@
1
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
2
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
3
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
4
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
5
+ 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); }
1
6
  function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
2
7
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
3
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."); }
@@ -17,7 +22,9 @@ export function createSendEventForFacet(_ref) {
17
22
  }
18
23
  var facetValue = args[1],
19
24
  _args$ = args[2],
20
- eventName = _args$ === void 0 ? 'Filter Applied' : _args$;
25
+ eventName = _args$ === void 0 ? 'Filter Applied' : _args$,
26
+ _args$2 = args[3],
27
+ additionalData = _args$2 === void 0 ? {} : _args$2;
21
28
  var _args$0$split = args[0].split(':'),
22
29
  _args$0$split2 = _slicedToArray(_args$0$split, 2),
23
30
  eventType = _args$0$split2[0],
@@ -25,7 +32,7 @@ export function createSendEventForFacet(_ref) {
25
32
  var attribute = typeof attr === 'string' ? attr : attr(facetValue);
26
33
  if (args.length === 1 && _typeof(args[0]) === 'object') {
27
34
  instantSearchInstance.sendEventToInsights(args[0]);
28
- } else if (eventType === 'click' && (args.length === 2 || args.length === 3)) {
35
+ } else if (eventType === 'click' && args.length >= 2 && args.length <= 4) {
29
36
  if (!isFacetRefined(helper, attribute, facetValue)) {
30
37
  // send event only when the facet is being checked "ON"
31
38
  instantSearchInstance.sendEventToInsights({
@@ -33,16 +40,16 @@ export function createSendEventForFacet(_ref) {
33
40
  widgetType: widgetType,
34
41
  eventType: eventType,
35
42
  eventModifier: eventModifier,
36
- payload: {
43
+ payload: _objectSpread({
37
44
  eventName: eventName,
38
45
  index: helper.getIndex(),
39
46
  filters: ["".concat(attribute, ":").concat(facetValue)]
40
- },
47
+ }, additionalData),
41
48
  attribute: attribute
42
49
  });
43
50
  }
44
51
  } else if (process.env.NODE_ENV === 'development') {
45
- throw new Error("You need to pass two arguments like:\n sendEvent('click', facetValue);\n\nIf you want to send a custom payload, you can pass one object: sendEvent(customPayload);\n");
52
+ throw new Error("You need to pass between two and four arguments like:\n sendEvent('click', facetValue, eventName?, additionalData?);\n\nIf you want to send a custom payload, you can pass one object: sendEvent(customPayload);\n");
46
53
  }
47
54
  };
48
55
  return sendEventForFacet;
@@ -1,9 +1,9 @@
1
1
  import type { InsightsEvent } from '../../middlewares/createInsightsMiddleware';
2
2
  import type { InstantSearch, Hit } from '../../types';
3
- type BuiltInSendEventForHits = (eventType: string, hits: Hit | Hit[], eventName?: string) => void;
3
+ type BuiltInSendEventForHits = (eventType: string, hits: Hit | Hit[], eventName?: string, additionalData?: Record<string, any>) => void;
4
4
  type CustomSendEventForHits = (customPayload: any) => void;
5
5
  export type SendEventForHits = BuiltInSendEventForHits & CustomSendEventForHits;
6
- export type BuiltInBindEventForHits = (eventType: string, hits: Hit | Hit[], eventName?: string) => string;
6
+ export type BuiltInBindEventForHits = (eventType: string, hits: Hit | Hit[], eventName?: string, additionalData?: Record<string, any>) => string;
7
7
  export type CustomBindEventForHits = (customPayload: any) => string;
8
8
  export type BindEventForHits = BuiltInBindEventForHits & CustomBindEventForHits;
9
9
  export declare function _buildEventPayloadsForHits({ index, widgetType, methodName, args, instantSearchInstance, }: {
@@ -1,3 +1,8 @@
1
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
2
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
3
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
4
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
5
+ 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); }
1
6
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
7
  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."); }
3
8
  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); }
@@ -30,6 +35,7 @@ export function _buildEventPayloadsForHits(_ref) {
30
35
  eventModifier = _args$0$split2[1];
31
36
  var hits = args[1];
32
37
  var eventName = args[2];
38
+ var additionalData = args[3] || {};
33
39
  if (!hits) {
34
40
  if (process.env.NODE_ENV === 'development') {
35
41
  throw new Error("You need to pass hit or hits as the second argument like:\n ".concat(methodName, "(eventType, hit);\n "));
@@ -69,11 +75,11 @@ export function _buildEventPayloadsForHits(_ref) {
69
75
  insightsMethod: 'viewedObjectIDs',
70
76
  widgetType: widgetType,
71
77
  eventType: eventType,
72
- payload: {
78
+ payload: _objectSpread({
73
79
  eventName: eventName || 'Hits Viewed',
74
80
  index: index,
75
81
  objectIDs: objectIDsByChunk[i]
76
- },
82
+ }, additionalData),
77
83
  hits: batch,
78
84
  eventModifier: eventModifier
79
85
  };
@@ -84,13 +90,13 @@ export function _buildEventPayloadsForHits(_ref) {
84
90
  insightsMethod: 'clickedObjectIDsAfterSearch',
85
91
  widgetType: widgetType,
86
92
  eventType: eventType,
87
- payload: {
93
+ payload: _objectSpread({
88
94
  eventName: eventName || 'Hit Clicked',
89
95
  index: index,
90
96
  queryID: queryID,
91
97
  objectIDs: objectIDsByChunk[i],
92
98
  positions: positionsByChunk[i]
93
- },
99
+ }, additionalData),
94
100
  hits: batch,
95
101
  eventModifier: eventModifier
96
102
  };
@@ -101,12 +107,12 @@ export function _buildEventPayloadsForHits(_ref) {
101
107
  insightsMethod: 'convertedObjectIDsAfterSearch',
102
108
  widgetType: widgetType,
103
109
  eventType: eventType,
104
- payload: {
110
+ payload: _objectSpread({
105
111
  eventName: eventName || 'Hit Converted',
106
112
  index: index,
107
113
  queryID: queryID,
108
114
  objectIDs: objectIDsByChunk[i]
109
- },
115
+ }, additionalData),
110
116
  hits: batch,
111
117
  eventModifier: eventModifier
112
118
  };
@@ -1,2 +1,2 @@
1
- declare const _default: "4.57.0";
1
+ declare const _default: "4.59.0";
2
2
  export default _default;
package/es/lib/version.js CHANGED
@@ -1 +1 @@
1
- export default '4.57.0';
1
+ export default '4.59.0';
@@ -24,7 +24,9 @@ export function createInsightsMiddleware() {
24
24
  insightsInitParams = props.insightsInitParams,
25
25
  onEvent = props.onEvent,
26
26
  _props$$$internal = props.$$internal,
27
- $$internal = _props$$$internal === void 0 ? false : _props$$$internal;
27
+ $$internal = _props$$$internal === void 0 ? false : _props$$$internal,
28
+ _props$$$automatic = props.$$automatic,
29
+ $$automatic = _props$$$automatic === void 0 ? false : _props$$$automatic;
28
30
  var potentialInsightsClient = _insightsClient;
29
31
  if (!_insightsClient && _insightsClient !== null) {
30
32
  safelyRunOnBrowser(function (_ref) {
@@ -115,6 +117,7 @@ export function createInsightsMiddleware() {
115
117
  return {
116
118
  $$type: 'ais.insights',
117
119
  $$internal: $$internal,
120
+ $$automatic: $$automatic,
118
121
  onStateChange: function onStateChange() {},
119
122
  subscribe: function subscribe() {
120
123
  if (!insightsClient.shouldAddScript) return;
@@ -135,14 +138,19 @@ export function createInsightsMiddleware() {
135
138
  },
136
139
  started: function started() {
137
140
  insightsClient('addAlgoliaAgent', 'insights-middleware');
138
- helper = instantSearchInstance.helper;
141
+ helper = instantSearchInstance.mainHelper;
139
142
  initialParameters = {
140
143
  userToken: helper.state.userToken,
141
144
  clickAnalytics: helper.state.clickAnalytics
142
145
  };
143
- helper.overrideStateWithoutTriggeringChangeEvent(_objectSpread(_objectSpread({}, helper.state), {}, {
144
- clickAnalytics: true
145
- }));
146
+
147
+ // We don't want to force clickAnalytics when the insights is enabled from the search response.
148
+ // This means we don't enable insights for indices that don't opt in
149
+ if (!$$automatic) {
150
+ helper.overrideStateWithoutTriggeringChangeEvent(_objectSpread(_objectSpread({}, helper.state), {}, {
151
+ clickAnalytics: true
152
+ }));
153
+ }
146
154
  if (!$$internal) {
147
155
  instantSearchInstance.scheduleSearch();
148
156
  }
@@ -209,6 +217,9 @@ export function createInsightsMiddleware() {
209
217
  } else if (event.insightsMethod) {
210
218
  // Source is used to differentiate events sent by instantsearch from those sent manually.
211
219
  event.payload.algoliaSource = ['instantsearch'];
220
+ if ($$automatic) {
221
+ event.payload.algoliaSource.push('instantsearch-automatic');
222
+ }
212
223
  if (event.eventModifier === 'internal') {
213
224
  event.payload.algoliaSource.push('instantsearch-internal');
214
225
  }
@@ -207,7 +207,7 @@ var index = function index(widgetParams) {
207
207
  return widgets.indexOf(widget) === -1;
208
208
  });
209
209
  if (localInstantSearchInstance && Boolean(widgets.length)) {
210
- var _nextState = widgets.reduce(function (state, widget) {
210
+ var cleanedState = widgets.reduce(function (state, widget) {
211
211
  // the `dispose` method exists at this point we already assert it
212
212
  var next = widget.dispose({
213
213
  helper: helper,
@@ -216,14 +216,23 @@ var index = function index(widgetParams) {
216
216
  });
217
217
  return next || state;
218
218
  }, helper.state);
219
+ var newState = localInstantSearchInstance.future.preserveSharedStateOnUnmount ? getLocalWidgetsSearchParameters(localWidgets, {
220
+ uiState: localUiState,
221
+ initialSearchParameters: new algoliasearchHelper.SearchParameters({
222
+ index: this.getIndexName()
223
+ })
224
+ }) : getLocalWidgetsSearchParameters(localWidgets, {
225
+ uiState: getLocalWidgetsUiState(localWidgets, {
226
+ searchParameters: cleanedState,
227
+ helper: helper
228
+ }),
229
+ initialSearchParameters: cleanedState
230
+ });
219
231
  localUiState = getLocalWidgetsUiState(localWidgets, {
220
- searchParameters: _nextState,
232
+ searchParameters: newState,
221
233
  helper: helper
222
234
  });
223
- helper.setState(getLocalWidgetsSearchParameters(localWidgets, {
224
- uiState: localUiState,
225
- initialSearchParameters: _nextState
226
- }));
235
+ helper.setState(newState);
227
236
  if (localWidgets.length) {
228
237
  localInstantSearchInstance.scheduleSearch();
229
238
  }
@@ -289,7 +298,7 @@ var index = function index(widgetParams) {
289
298
  return mainHelper.searchForFacetValues(facetName, facetValue, maxFacetHits, state);
290
299
  };
291
300
  derivedHelper = mainHelper.derive(function () {
292
- return mergeSearchParameters.apply(void 0, _toConsumableArray(resolveSearchParameters(_this3)));
301
+ return mergeSearchParameters.apply(void 0, [mainHelper.state].concat(_toConsumableArray(resolveSearchParameters(_this3))));
293
302
  });
294
303
  var indexInitialResults = (_instantSearchInstanc = instantSearchInstance._initialResults) === null || _instantSearchInstanc === void 0 ? void 0 : _instantSearchInstanc[this.getIndexId()];
295
304
  if (indexInitialResults) {
@@ -30,7 +30,8 @@ var renderer = function renderer(_ref) {
30
30
  cssClasses: cssClasses,
31
31
  currentValue: currentRefinement,
32
32
  options: options,
33
- setValue: refine
33
+ setValue: refine,
34
+ ariaLabel: "Sort results by"
34
35
  })), containerNode);
35
36
  };
36
37
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instantsearch.js",
3
- "version": "4.57.0",
3
+ "version": "4.59.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",
@@ -27,13 +27,13 @@
27
27
  ],
28
28
  "dependencies": {
29
29
  "@algolia/events": "^4.0.1",
30
- "@algolia/ui-components-highlight-vdom": "^1.2.1",
31
- "@algolia/ui-components-shared": "^1.2.1",
30
+ "@algolia/ui-components-highlight-vdom": "^1.2.2",
31
+ "@algolia/ui-components-shared": "^1.2.2",
32
32
  "@types/dom-speech-recognition": "^0.0.1",
33
33
  "@types/google.maps": "^3.45.3",
34
34
  "@types/hogan.js": "^3.0.0",
35
35
  "@types/qs": "^6.5.3",
36
- "algoliasearch-helper": "3.14.2",
36
+ "algoliasearch-helper": "3.15.0",
37
37
  "hogan.js": "^3.0.2",
38
38
  "htm": "^3.0.0",
39
39
  "preact": "^10.10.0",
@@ -55,9 +55,9 @@
55
55
  "version": "./scripts/version/update-version.js"
56
56
  },
57
57
  "devDependencies": {
58
- "@instantsearch/mocks": "1.26.0",
59
- "@instantsearch/tests": "1.26.0",
60
- "@instantsearch/testutils": "1.15.0",
58
+ "@instantsearch/mocks": "1.28.0",
59
+ "@instantsearch/tests": "1.28.0",
60
+ "@instantsearch/testutils": "1.17.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": "b2196f01f03c6bea37a3aa048e4e5b45a9bbf33d"
68
+ "gitHead": "8fb537f2301a5e133e9e5df20c7c208cae16b3aa"
69
69
  }