instantsearch.js 4.55.0 → 4.56.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 (70) hide show
  1. package/cjs/components/Breadcrumb/Breadcrumb.js +2 -2
  2. package/cjs/components/Hits/Hits.js +4 -0
  3. package/cjs/components/InfiniteHits/InfiniteHits.js +4 -0
  4. package/cjs/components/RangeInput/RangeInput.js +22 -11
  5. package/cjs/components/RefinementList/RefinementList.js +34 -52
  6. package/cjs/components/Slider/Rheostat.js +163 -249
  7. package/cjs/connectors/infinite-hits/connectInfiniteHits.js +22 -7
  8. package/cjs/lib/InstantSearch.js +2 -4
  9. package/cjs/lib/routers/history.js +54 -1
  10. package/cjs/lib/utils/escape-highlight.js +2 -0
  11. package/cjs/lib/utils/getHighlightedParts.js +1 -0
  12. package/cjs/lib/utils/render-args.js +3 -2
  13. package/cjs/lib/version.js +1 -1
  14. package/cjs/widgets/hits-per-page/hits-per-page.js +3 -1
  15. package/cjs/widgets/index/index.js +8 -8
  16. package/dist/instantsearch.development.d.ts +76 -76
  17. package/dist/instantsearch.development.js +356 -341
  18. package/dist/instantsearch.development.js.map +1 -1
  19. package/dist/instantsearch.production.d.ts +76 -76
  20. package/dist/instantsearch.production.min.d.ts +76 -76
  21. package/dist/instantsearch.production.min.js +2 -2
  22. package/dist/instantsearch.production.min.js.map +1 -1
  23. package/es/components/Breadcrumb/Breadcrumb.d.ts +2 -2
  24. package/es/components/Breadcrumb/Breadcrumb.js +2 -2
  25. package/es/components/GeoSearchControls/GeoSearchButton.d.ts +1 -1
  26. package/es/components/GeoSearchControls/GeoSearchControls.d.ts +3 -3
  27. package/es/components/GeoSearchControls/GeoSearchToggle.d.ts +1 -1
  28. package/es/components/Hits/Hits.js +4 -0
  29. package/es/components/InfiniteHits/InfiniteHits.js +4 -0
  30. package/es/components/Pagination/Pagination.d.ts +2 -2
  31. package/es/components/RangeInput/RangeInput.d.ts +7 -4
  32. package/es/components/RangeInput/RangeInput.js +22 -11
  33. package/es/components/RefinementList/RefinementList.d.ts +0 -1
  34. package/es/components/RefinementList/RefinementList.js +34 -52
  35. package/es/components/RelevantSort/RelevantSort.d.ts +1 -1
  36. package/es/components/Selector/Selector.d.ts +2 -2
  37. package/es/components/Slider/Rheostat.d.ts +23 -17
  38. package/es/components/Slider/Rheostat.js +163 -249
  39. package/es/components/Slider/Slider.d.ts +1 -1
  40. package/es/connectors/current-refinements/connectCurrentRefinements.d.ts +2 -2
  41. package/es/connectors/dynamic-widgets/connectDynamicWidgets.d.ts +2 -2
  42. package/es/connectors/geo-search/connectGeoSearch.d.ts +7 -7
  43. package/es/connectors/infinite-hits/connectInfiniteHits.js +23 -8
  44. package/es/connectors/menu/connectMenu.d.ts +2 -2
  45. package/es/connectors/pagination/connectPagination.d.ts +1 -1
  46. package/es/connectors/range/connectRange.d.ts +3 -3
  47. package/es/connectors/refinement-list/connectRefinementList.d.ts +3 -3
  48. package/es/connectors/relevant-sort/connectRelevantSort.d.ts +1 -1
  49. package/es/lib/InstantSearch.d.ts +13 -13
  50. package/es/lib/InstantSearch.js +3 -5
  51. package/es/lib/routers/history.d.ts +2 -2
  52. package/es/lib/routers/history.js +55 -2
  53. package/es/lib/utils/defer.d.ts +2 -2
  54. package/es/lib/utils/escape-highlight.js +2 -0
  55. package/es/lib/utils/getHighlightedParts.js +1 -0
  56. package/es/lib/utils/render-args.js +3 -2
  57. package/es/lib/version.d.ts +1 -1
  58. package/es/lib/version.js +1 -1
  59. package/es/types/middleware.d.ts +6 -6
  60. package/es/types/router.d.ts +7 -7
  61. package/es/types/widget.d.ts +1 -1
  62. package/es/widgets/dynamic-widgets/dynamic-widgets.d.ts +2 -2
  63. package/es/widgets/geo-search/createHTMLMarker.d.ts +1 -1
  64. package/es/widgets/geo-search/geo-search.d.ts +1 -1
  65. package/es/widgets/hits-per-page/hits-per-page.js +3 -1
  66. package/es/widgets/index/index.d.ts +20 -20
  67. package/es/widgets/index/index.js +8 -8
  68. package/es/widgets/panel/panel.d.ts +2 -2
  69. package/es/widgets/range-slider/range-slider.d.ts +1 -1
  70. package/package.json +6 -6
@@ -53,7 +53,7 @@ export type CurrentRefinementsConnectorParamsItem = {
53
53
  /**
54
54
  * Removes the given refinement and triggers a new search.
55
55
  */
56
- refine(refinement: CurrentRefinementsConnectorParamsRefinement): void;
56
+ refine: (refinement: CurrentRefinementsConnectorParamsRefinement) => void;
57
57
  };
58
58
  export type CurrentRefinementsConnectorParams = {
59
59
  /**
@@ -87,7 +87,7 @@ export type CurrentRefinementsRenderState = {
87
87
  /**
88
88
  * Removes the given refinement and triggers a new search.
89
89
  */
90
- refine(refinement: CurrentRefinementsConnectorParamsRefinement): void;
90
+ refine: (refinement: CurrentRefinementsConnectorParamsRefinement) => void;
91
91
  /**
92
92
  * Generates a URL for the next state.
93
93
  */
@@ -11,10 +11,10 @@ export type DynamicWidgetsConnectorParams = {
11
11
  * Function to return a fallback widget when an attribute isn't found in
12
12
  * `widgets`.
13
13
  */
14
- fallbackWidget?(args: {
14
+ fallbackWidget?: (args: {
15
15
  /** The attribute name to create a widget for. */
16
16
  attribute: string;
17
- }): Widget;
17
+ }) => Widget;
18
18
  /**
19
19
  * Function to transform the items to render.
20
20
  * The function also exposes the full search response.
@@ -15,7 +15,7 @@ export type GeoSearchRenderState<THit extends BaseHit = Record<string, any>> = {
15
15
  /**
16
16
  * Reset the current bounding box refinement.
17
17
  */
18
- clearMapRefinement(): void;
18
+ clearMapRefinement: () => void;
19
19
  /**
20
20
  * The current bounding box of the search.
21
21
  */
@@ -23,15 +23,15 @@ export type GeoSearchRenderState<THit extends BaseHit = Record<string, any>> = {
23
23
  /**
24
24
  * Return true if the map has move since the last refinement.
25
25
  */
26
- hasMapMoveSinceLastRefine(): boolean;
26
+ hasMapMoveSinceLastRefine: () => boolean;
27
27
  /**
28
28
  * Return true if the current refinement is set with the map bounds.
29
29
  */
30
- isRefinedWithMap(): boolean;
30
+ isRefinedWithMap: () => boolean;
31
31
  /**
32
32
  * Return true if the user is able to refine on map move.
33
33
  */
34
- isRefineOnMapMove(): boolean;
34
+ isRefineOnMapMove: () => boolean;
35
35
  /**
36
36
  * The matched hits from Algolia API.
37
37
  */
@@ -43,7 +43,7 @@ export type GeoSearchRenderState<THit extends BaseHit = Record<string, any>> = {
43
43
  /**
44
44
  * Sets a bounding box to filter the results from the given map bounds.
45
45
  */
46
- refine(bounds: Bounds): void;
46
+ refine: (bounds: Bounds) => void;
47
47
  /**
48
48
  * Send event to insights middleware
49
49
  */
@@ -53,11 +53,11 @@ export type GeoSearchRenderState<THit extends BaseHit = Record<string, any>> = {
53
53
  * called on each map move. The call to the function triggers a new rendering
54
54
  * only when the value change.
55
55
  */
56
- setMapMoveSinceLastRefine(): void;
56
+ setMapMoveSinceLastRefine: () => void;
57
57
  /**
58
58
  * Toggle the fact that the user is able to refine on map move.
59
59
  */
60
- toggleRefineOnMapMove(): void;
60
+ toggleRefineOnMapMove: () => void;
61
61
  };
62
62
  export type GeoSearchConnectorParams<THit extends BaseHit = Record<string, any>> = {
63
63
  /**
@@ -14,7 +14,7 @@ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToAr
14
14
  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; }
15
15
  function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
16
16
  function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
17
- import { escapeHits, TAG_PLACEHOLDER, checkRendering, createDocumentationMessageGenerator, isEqual, addAbsolutePosition, addQueryID, noop, createSendEventForHits, createBindEventForHits } from "../../lib/utils/index.js";
17
+ import { escapeHits, TAG_PLACEHOLDER, checkRendering, createDocumentationMessageGenerator, isEqual, addAbsolutePosition, addQueryID, noop, createSendEventForHits, createBindEventForHits, walkIndex } from "../../lib/utils/index.js";
18
18
  var withUsage = createDocumentationMessageGenerator({
19
19
  name: 'infinite-hits',
20
20
  connector: true
@@ -165,6 +165,7 @@ var connectInfiniteHits = function connectInfiniteHits(renderFn) {
165
165
  });
166
166
  isFirstPage = state.page === undefined || getFirstReceivedPage(state, cachedHits) === 0;
167
167
  } else {
168
+ var _results$disjunctiveF, _results$facets, _results$hierarchical;
168
169
  var _state$page3 = state.page,
169
170
  _page = _state$page3 === void 0 ? 0 : _state$page3;
170
171
  if (escapeHTML && results.hits.length > 0) {
@@ -175,7 +176,21 @@ var connectInfiniteHits = function connectInfiniteHits(renderFn) {
175
176
  var transformedHits = transformItems(hitsWithAbsolutePositionAndQueryID, {
176
177
  results: results
177
178
  });
178
- if (cachedHits[_page] === undefined && !results.__isArtificial && instantSearchInstance.status === 'idle') {
179
+
180
+ /*
181
+ With dynamic widgets, facets are not included in the state before their relevant widgets are mounted. Until then, we need to bail out of writing this incomplete state representation in cache.
182
+ */
183
+ var hasDynamicWidgets = false;
184
+ walkIndex(instantSearchInstance.mainIndex, function (indexWidget) {
185
+ if (!hasDynamicWidgets && indexWidget.getWidgets().some(function (_ref7) {
186
+ var $$type = _ref7.$$type;
187
+ return $$type === 'ais.dynamicWidgets';
188
+ })) {
189
+ hasDynamicWidgets = true;
190
+ }
191
+ });
192
+ var hasNoFacets = !((_results$disjunctiveF = results.disjunctiveFacets) !== null && _results$disjunctiveF !== void 0 && _results$disjunctiveF.length) && !((_results$facets = results.facets) !== null && _results$facets !== void 0 && _results$facets.length) && !((_results$hierarchical = results.hierarchicalFacets) !== null && _results$hierarchical !== void 0 && _results$hierarchical.length);
193
+ if (cachedHits[_page] === undefined && !results.__isArtificial && instantSearchInstance.status === 'idle' && !(hasDynamicWidgets && hasNoFacets)) {
179
194
  cachedHits[_page] = transformedHits;
180
195
  cache.write({
181
196
  state: normalizeState(state),
@@ -200,8 +215,8 @@ var connectInfiniteHits = function connectInfiniteHits(renderFn) {
200
215
  widgetParams: widgetParams
201
216
  };
202
217
  },
203
- dispose: function dispose(_ref7) {
204
- var state = _ref7.state;
218
+ dispose: function dispose(_ref8) {
219
+ var state = _ref8.state;
205
220
  unmountFn();
206
221
  var stateWithoutPage = state.setQueryParameter('page', undefined);
207
222
  if (!escapeHTML) {
@@ -211,8 +226,8 @@ var connectInfiniteHits = function connectInfiniteHits(renderFn) {
211
226
  return _objectSpread(_objectSpread({}, acc), {}, _defineProperty({}, key, undefined));
212
227
  }, {}));
213
228
  },
214
- getWidgetUiState: function getWidgetUiState(uiState, _ref8) {
215
- var searchParameters = _ref8.searchParameters;
229
+ getWidgetUiState: function getWidgetUiState(uiState, _ref9) {
230
+ var searchParameters = _ref9.searchParameters;
216
231
  var page = searchParameters.page || 0;
217
232
  if (!page) {
218
233
  // return without adding `page` to uiState
@@ -225,8 +240,8 @@ var connectInfiniteHits = function connectInfiniteHits(renderFn) {
225
240
  page: page + 1
226
241
  });
227
242
  },
228
- getWidgetSearchParameters: function getWidgetSearchParameters(searchParameters, _ref9) {
229
- var uiState = _ref9.uiState;
243
+ getWidgetSearchParameters: function getWidgetSearchParameters(searchParameters, _ref10) {
244
+ var uiState = _ref10.uiState;
230
245
  var widgetSearchParameters = searchParameters;
231
246
  if (escapeHTML) {
232
247
  widgetSearchParameters = searchParameters.setQueryParameters(TAG_PLACEHOLDER);
@@ -61,7 +61,7 @@ export type MenuRenderState = {
61
61
  /**
62
62
  * Filter the search to item value.
63
63
  */
64
- refine(value: string): void;
64
+ refine: (value: string) => void;
65
65
  /**
66
66
  * True if refinement can be applied.
67
67
  */
@@ -73,7 +73,7 @@ export type MenuRenderState = {
73
73
  /**
74
74
  * Toggles the number of values displayed between `limit` and `showMore.limit`.
75
75
  */
76
- toggleShowMore(): void;
76
+ toggleShowMore: () => void;
77
77
  /**
78
78
  * `true` if the toggleShowMore button can be activated (enough items to display more or
79
79
  * already displaying more than `limit` items)
@@ -14,7 +14,7 @@ export type PaginationRenderState = {
14
14
  /** Creates URLs for the next state, the number is the page to generate the URL for. */
15
15
  createURL: CreateURL<number>;
16
16
  /** Sets the current page and triggers a search. */
17
- refine(page: number): void;
17
+ refine: (page: number) => void;
18
18
  /** true if this search returned more than one page */
19
19
  canRefine: boolean;
20
20
  /** The number of the page currently displayed. */
@@ -14,7 +14,7 @@ export type RangeRenderState = {
14
14
  * previously set bound or to set an infinite bound.
15
15
  * @param rangeValue tuple of [min, max] bounds
16
16
  */
17
- refine(rangeValue: RangeBoundaries): void;
17
+ refine: (rangeValue: RangeBoundaries) => void;
18
18
  /**
19
19
  * Indicates whether this widget can be refined
20
20
  */
@@ -36,8 +36,8 @@ export type RangeRenderState = {
36
36
  * Both functions take a `number` as input and should output a `string`.
37
37
  */
38
38
  format: {
39
- from(fromValue: number): string;
40
- to(toValue: number): string;
39
+ from: (fromValue: number) => string;
40
+ to: (toValue: number) => string;
41
41
  };
42
42
  };
43
43
  export type RangeConnectorParams = {
@@ -79,7 +79,7 @@ export type RefinementListRenderState = {
79
79
  /**
80
80
  * Action to apply selected refinements.
81
81
  */
82
- refine(value: string): void;
82
+ refine: (value: string) => void;
83
83
  /**
84
84
  * Send event to insights middleware
85
85
  */
@@ -87,7 +87,7 @@ export type RefinementListRenderState = {
87
87
  /**
88
88
  * Searches for values inside the list.
89
89
  */
90
- searchForItems(query: string): void;
90
+ searchForItems: (query: string) => void;
91
91
  /**
92
92
  * `true` if the values are from an index search.
93
93
  */
@@ -108,7 +108,7 @@ export type RefinementListRenderState = {
108
108
  /**
109
109
  * Toggles the number of values displayed between `limit` and `showMoreLimit`.
110
110
  */
111
- toggleShowMore(): void;
111
+ toggleShowMore: () => void;
112
112
  };
113
113
  export type RefinementListWidgetDescription = {
114
114
  $$type: 'ais.refinementList';
@@ -1,6 +1,6 @@
1
1
  import type { Connector, WidgetRenderState } from '../../types';
2
2
  export type RelevantSortConnectorParams = Record<string, unknown>;
3
- type Refine = (relevancyStrictness: number) => void;
3
+ type Refine = (relevancyStrictness: number | undefined) => void;
4
4
  export type RelevantSortRenderState = {
5
5
  /**
6
6
  * Indicates if it has appliedRelevancyStrictness greater than zero
@@ -10,9 +10,9 @@ type NoInfer<T> = T extends infer S ? S : never;
10
10
  */
11
11
  export type InstantSearchOptions<TUiState extends UiState = UiState, TRouteState = TUiState> = {
12
12
  /**
13
- * The name of the main index
13
+ * The name of the main index. If no indexName is provided, you have to manually add an index widget.
14
14
  */
15
- indexName: string;
15
+ indexName?: string;
16
16
  /**
17
17
  * The search client to plug to InstantSearch.js
18
18
  *
@@ -61,7 +61,7 @@ export type InstantSearchOptions<TUiState extends UiState = UiState, TRouteState
61
61
  */
62
62
  onStateChange?: (params: {
63
63
  uiState: TUiState;
64
- setUiState(uiState: TUiState | ((previousUiState: TUiState) => TUiState)): void;
64
+ setUiState: (uiState: TUiState | ((previousUiState: TUiState) => TUiState)) => void;
65
65
  }) => void;
66
66
  /**
67
67
  * Injects a `uiState` to the `instantsearch` instance. You can use this option
@@ -122,8 +122,8 @@ declare class InstantSearch<TUiState extends UiState = UiState, TRouteState = TU
122
122
  _searchFunction?: InstantSearchOptions['searchFunction'];
123
123
  _mainHelperSearch?: AlgoliaSearchHelper['search'];
124
124
  middleware: Array<{
125
- creator: Middleware;
126
- instance: MiddlewareDefinition;
125
+ creator: Middleware<TUiState>;
126
+ instance: MiddlewareDefinition<TUiState>;
127
127
  }>;
128
128
  sendEventToInsights: (event: InsightsEvent) => void;
129
129
  /**
@@ -143,11 +143,11 @@ declare class InstantSearch<TUiState extends UiState = UiState, TRouteState = TU
143
143
  /**
144
144
  * Hooks a middleware into the InstantSearch lifecycle.
145
145
  */
146
- use(...middleware: Middleware[]): this;
146
+ use(...middleware: Array<Middleware<TUiState>>): this;
147
147
  /**
148
148
  * Removes a middleware from the InstantSearch lifecycle.
149
149
  */
150
- unuse(...middlewareToUnuse: Middleware[]): this;
150
+ unuse(...middlewareToUnuse: Array<Middleware<TUiState>>): this;
151
151
  EXPERIMENTAL_use(...middleware: Middleware[]): this;
152
152
  /**
153
153
  * Adds a widget to the search instance.
@@ -193,12 +193,12 @@ declare class InstantSearch<TUiState extends UiState = UiState, TRouteState = TU
193
193
  */
194
194
  dispose(): void;
195
195
  scheduleSearch: (() => void) & {
196
- wait(): Promise<void>;
197
- cancel(): void;
196
+ wait: () => Promise<void>;
197
+ cancel: () => void;
198
198
  };
199
199
  scheduleRender: ((shouldResetStatus?: boolean) => void) & {
200
- wait(): Promise<void>;
201
- cancel(): void;
200
+ wait: () => Promise<void>;
201
+ cancel: () => void;
202
202
  };
203
203
  scheduleStalledRender(): void;
204
204
  /**
@@ -209,8 +209,8 @@ declare class InstantSearch<TUiState extends UiState = UiState, TRouteState = TU
209
209
  setUiState(uiState: TUiState | ((previousUiState: TUiState) => TUiState), callOnStateChange?: boolean): void;
210
210
  getUiState(): TUiState;
211
211
  onInternalStateChange: (() => void) & {
212
- wait(): Promise<void>;
213
- cancel(): void;
212
+ wait: () => Promise<void>;
213
+ cancel: () => void;
214
214
  };
215
215
  createURL(nextState?: TUiState): string;
216
216
  refresh(): void;
@@ -21,7 +21,7 @@ import { createMetadataMiddleware, isMetadataEnabled } from "../middlewares/crea
21
21
  import { createRouterMiddleware } from "../middlewares/createRouterMiddleware.js";
22
22
  import index from "../widgets/index/index.js";
23
23
  import createHelpers from "./createHelpers.js";
24
- import { createDocumentationMessageGenerator, createDocumentationLink, defer, noop, warning, setIndexHelperState } from "./utils/index.js";
24
+ import { createDocumentationMessageGenerator, createDocumentationLink, defer, noop, warning, setIndexHelperState, isIndexWidget } from "./utils/index.js";
25
25
  import version from "./version.js";
26
26
  var withUsage = createDocumentationMessageGenerator({
27
27
  name: 'instantsearch'
@@ -100,7 +100,7 @@ var InstantSearch = /*#__PURE__*/function (_EventEmitter) {
100
100
  }));
101
101
  _this.setMaxListeners(100);
102
102
  var _options$indexName = options.indexName,
103
- indexName = _options$indexName === void 0 ? null : _options$indexName,
103
+ indexName = _options$indexName === void 0 ? '' : _options$indexName,
104
104
  numberLocale = options.numberLocale,
105
105
  _options$initialUiSta = options.initialUiState,
106
106
  initialUiState = _options$initialUiSta === void 0 ? {} : _options$initialUiSta,
@@ -117,9 +117,6 @@ var InstantSearch = /*#__PURE__*/function (_EventEmitter) {
117
117
  insightsClient = _options$insightsClie === void 0 ? null : _options$insightsClie,
118
118
  _options$onStateChang = options.onStateChange,
119
119
  onStateChange = _options$onStateChang === void 0 ? null : _options$onStateChang;
120
- if (indexName === null) {
121
- throw new Error(withUsage('The `indexName` option is required.'));
122
- }
123
120
  if (searchClient === null) {
124
121
  throw new Error(withUsage('The `searchClient` option is required.'));
125
122
  }
@@ -361,6 +358,7 @@ var InstantSearch = /*#__PURE__*/function (_EventEmitter) {
361
358
  mainHelper.search = function () {
362
359
  _this3.status = 'loading';
363
360
  _this3.scheduleRender(false);
361
+ process.env.NODE_ENV === 'development' ? warning(Boolean(_this3.indexName) || _this3.mainIndex.getWidgets().some(isIndexWidget), 'No indexName provided, nor an explicit index widget in the widgets tree. This is required to be able to display results.') : void 0;
364
362
 
365
363
  // This solution allows us to keep the exact same API for the users but
366
364
  // under the hood, we have a different implementation. It should be
@@ -14,7 +14,7 @@ export type BrowserHistoryArgs<TRouteState> = {
14
14
  writeDelay: number;
15
15
  createURL: CreateURL<TRouteState>;
16
16
  parseURL: ParseURL<TRouteState>;
17
- getLocation(): Location;
17
+ getLocation: () => Location;
18
18
  start?: (onUpdate: () => void) => void;
19
19
  dispose?: () => void;
20
20
  push?: (url: string) => void;
@@ -49,7 +49,7 @@ declare class BrowserHistory<TRouteState> implements Router<TRouteState> {
49
49
  */
50
50
  private readonly getLocation;
51
51
  private writeTimer?;
52
- private _onPopState;
52
+ private _onPopState?;
53
53
  /**
54
54
  * Indicates if last action was back/forward in the browser.
55
55
  */
@@ -6,7 +6,7 @@ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key i
6
6
  function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
7
7
  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); }
8
8
  import qs from 'qs';
9
- import { safelyRunOnBrowser } from "../utils/index.js";
9
+ import { safelyRunOnBrowser, warning } from "../utils/index.js";
10
10
  var setWindowTitle = function setWindowTitle(title) {
11
11
  if (title) {
12
12
  // This function is only executed on browsers so we can disable this check.
@@ -15,6 +15,48 @@ var setWindowTitle = function setWindowTitle(title) {
15
15
  }
16
16
  };
17
17
  var BrowserHistory = /*#__PURE__*/function () {
18
+ /**
19
+ * Transforms a UI state into a title for the page.
20
+ */
21
+
22
+ /**
23
+ * Time in milliseconds before performing a write in the history.
24
+ * It prevents from adding too many entries in the history and
25
+ * makes the back button more usable.
26
+ *
27
+ * @default 400
28
+ */
29
+
30
+ /**
31
+ * Creates a full URL based on the route state.
32
+ * The storage adaptor maps all syncable keys to the query string of the URL.
33
+ */
34
+
35
+ /**
36
+ * Parses the URL into a route state.
37
+ * It should be symmetrical to `createURL`.
38
+ */
39
+
40
+ /**
41
+ * Returns the location to store in the history.
42
+ * @default () => window.location
43
+ */
44
+
45
+ /**
46
+ * Indicates if last action was back/forward in the browser.
47
+ */
48
+
49
+ /**
50
+ * Indicates whether the history router is disposed or not.
51
+ */
52
+
53
+ /**
54
+ * Indicates the window.history.length before the last call to
55
+ * window.history.pushState (called in `write`).
56
+ * It allows to determine if a `pushState` has been triggered elsewhere,
57
+ * and thus to prevent the `write` method from calling `pushState`.
58
+ */
59
+
18
60
  /**
19
61
  * Initializes a new storage provider that syncs the search state to the URL
20
62
  * using web APIs (`window.location.pushState` and `onpopstate` event).
@@ -38,6 +80,7 @@ var BrowserHistory = /*#__PURE__*/function () {
38
80
  _defineProperty(this, "parseURL", void 0);
39
81
  _defineProperty(this, "getLocation", void 0);
40
82
  _defineProperty(this, "writeTimer", void 0);
83
+ _defineProperty(this, "_onPopState", void 0);
41
84
  _defineProperty(this, "inPopState", false);
42
85
  _defineProperty(this, "isDisposed", false);
43
86
  _defineProperty(this, "latestAcknowledgedHistory", 0);
@@ -143,11 +186,21 @@ var BrowserHistory = /*#__PURE__*/function () {
143
186
  }, {
144
187
  key: "createURL",
145
188
  value: function createURL(routeState) {
146
- return this._createURL({
189
+ var url = this._createURL({
147
190
  qsModule: qs,
148
191
  routeState: routeState,
149
192
  location: this.getLocation()
150
193
  });
194
+ if (process.env.NODE_ENV === 'development') {
195
+ try {
196
+ // We just want to check if the URL is valid.
197
+ // eslint-disable-next-line no-new
198
+ new URL(url);
199
+ } catch (e) {
200
+ process.env.NODE_ENV === 'development' ? warning(false, "The URL returned by the `createURL` function is invalid.\nPlease make sure it returns an absolute URL to avoid issues, e.g: `https://algolia.com/search?query=iphone`.") : void 0;
201
+ }
202
+ }
203
+ return url;
151
204
  }
152
205
 
153
206
  /**
@@ -1,7 +1,7 @@
1
1
  type Callback = (...args: any[]) => void;
2
2
  type Defer = {
3
- wait(): Promise<void>;
4
- cancel(): void;
3
+ wait: () => Promise<void>;
4
+ cancel: () => void;
5
5
  };
6
6
  export declare function defer<TCallback extends Callback>(callback: TCallback): TCallback & Defer;
7
7
  export {};
@@ -16,6 +16,8 @@ export var TAG_REPLACEMENT = {
16
16
  highlightPreTag: '<mark>',
17
17
  highlightPostTag: '</mark>'
18
18
  };
19
+
20
+ // @MAJOR: in the future, this should only escape, not replace
19
21
  function replaceTagsAndEscape(value) {
20
22
  return escape(value).replace(new RegExp(TAG_PLACEHOLDER.highlightPreTag, 'g'), TAG_REPLACEMENT.highlightPreTag).replace(new RegExp(TAG_PLACEHOLDER.highlightPostTag, 'g'), TAG_REPLACEMENT.highlightPostTag);
21
23
  }
@@ -1,5 +1,6 @@
1
1
  import { TAG_REPLACEMENT } from "./escape-highlight.js";
2
2
  export function getHighlightedParts(highlightedValue) {
3
+ // @MAJOR: this should use TAG_PLACEHOLDER
3
4
  var highlightPostTag = TAG_REPLACEMENT.highlightPostTag,
4
5
  highlightPreTag = TAG_REPLACEMENT.highlightPreTag;
5
6
  var splitByPreTag = highlightedValue.split(highlightPreTag);
@@ -19,13 +19,14 @@ export function createInitArgs(instantSearchInstance, parent, uiState) {
19
19
  }
20
20
  export function createRenderArgs(instantSearchInstance, parent) {
21
21
  var results = parent.getResults();
22
+ var helper = parent.getHelper();
22
23
  return {
23
- helper: parent.getHelper(),
24
+ helper: helper,
24
25
  parent: parent,
25
26
  instantSearchInstance: instantSearchInstance,
26
27
  results: results,
27
28
  scopedResults: parent.getScopedResults(),
28
- state: results._state,
29
+ state: results ? results._state : helper.state,
29
30
  renderState: instantSearchInstance.renderState,
30
31
  templatesConfig: instantSearchInstance.templatesConfig,
31
32
  createURL: parent.createURL,
@@ -1,2 +1,2 @@
1
- declare const _default: "4.55.0";
1
+ declare const _default: "4.56.1";
2
2
  export default _default;
package/es/lib/version.js CHANGED
@@ -1 +1 @@
1
- export default '4.55.0';
1
+ export default '4.56.1';
@@ -9,24 +9,24 @@ export type MiddlewareDefinition<TUiState extends UiState = UiState> = {
9
9
  /**
10
10
  * Change handler called on every UiState change
11
11
  */
12
- onStateChange(options: {
12
+ onStateChange: (options: {
13
13
  uiState: TUiState;
14
- }): void;
14
+ }) => void;
15
15
  /**
16
16
  * Called when the middleware is added to InstantSearch
17
17
  */
18
- subscribe(): void;
18
+ subscribe: () => void;
19
19
  /**
20
20
  * Called when InstantSearch is started
21
21
  */
22
- started(): void;
22
+ started: () => void;
23
23
  /**
24
24
  * Called when the middleware is removed from InstantSearch
25
25
  */
26
- unsubscribe(): void;
26
+ unsubscribe: () => void;
27
27
  };
28
28
  export type MiddlewareOptions = {
29
29
  instantSearchInstance: InstantSearch;
30
30
  };
31
31
  export type InternalMiddleware<TUiState extends UiState = UiState> = (options: MiddlewareOptions) => MiddlewareDefinition<TUiState>;
32
- export type Middleware = (options: MiddlewareOptions) => AtLeastOne<MiddlewareDefinition>;
32
+ export type Middleware<TUiState extends UiState = UiState> = (options: MiddlewareOptions) => AtLeastOne<MiddlewareDefinition<TUiState>>;
@@ -10,26 +10,26 @@ export type Router<TRouteState = UiState> = {
10
10
  * In the case of the history / URL in a browser, the callback will be called
11
11
  * by `onPopState`.
12
12
  */
13
- onUpdate(callback: (route: TRouteState) => void): void;
13
+ onUpdate: (callback: (route: TRouteState) => void) => void;
14
14
  /**
15
15
  * Reads the storage and gets a route object. It does not take parameters,
16
16
  * and should return an object
17
17
  */
18
- read(): TRouteState;
18
+ read: () => TRouteState;
19
19
  /**
20
20
  * Pushes a route object into a storage. Takes the UI state mapped by the state
21
21
  * mapping configured in the mapping
22
22
  */
23
- write(route: TRouteState): void;
23
+ write: (route: TRouteState) => void;
24
24
  /**
25
25
  * Transforms a route object into a URL. It receives an object and should
26
26
  * return a string. It may return an empty string.
27
27
  */
28
- createURL(state: TRouteState): string;
28
+ createURL: (state: TRouteState) => string;
29
29
  /**
30
30
  * Called when InstantSearch is disposed. Used to remove subscriptions.
31
31
  */
32
- dispose(): void;
32
+ dispose: () => void;
33
33
  /**
34
34
  * Called when InstantSearch is started.
35
35
  */
@@ -52,13 +52,13 @@ export type StateMapping<TUiState = UiState, TRouteState = TUiState> = {
52
52
  * It should return an object of any form as long as this form can be read by
53
53
  * the `routeToState` function.
54
54
  */
55
- stateToRoute(uiState: TUiState): TRouteState;
55
+ stateToRoute: (uiState: TUiState) => TRouteState;
56
56
  /**
57
57
  * Transforms route object into a UI state representation.
58
58
  * It receives an object that contains the UI state stored by the router.
59
59
  * The format is the output of `stateToRoute`.
60
60
  */
61
- routeToState(routeState: TRouteState): TUiState;
61
+ routeToState: (routeState: TRouteState) => TUiState;
62
62
  /**
63
63
  * Identifier for this stateMapping. Used to differentiate between stateMappings.
64
64
  */
@@ -24,7 +24,7 @@ type SharedRenderOptions = {
24
24
  };
25
25
  status: InstantSearch['status'];
26
26
  error: InstantSearch['error'];
27
- createURL(state: SearchParameters): string;
27
+ createURL: (state: SearchParameters) => string;
28
28
  };
29
29
  export type InitOptions = SharedRenderOptions & {
30
30
  uiState: UiState;
@@ -14,12 +14,12 @@ export type DynamicWidgetsWidgetParams = {
14
14
  * Function to return a fallback widget when an attribute isn't found in
15
15
  * `widgets`.
16
16
  */
17
- fallbackWidget?(args: {
17
+ fallbackWidget?: (args: {
18
18
  /** The attribute name to create a widget for. */
19
19
  attribute: string;
20
20
  /** CSS Selector or HTMLElement to insert the widget */
21
21
  container: HTMLElement;
22
- }): Widget;
22
+ }) => Widget;
23
23
  };
24
24
  export type DynamicWidgetsWidget = WidgetFactory<DynamicWidgetsWidgetDescription & {
25
25
  $$widgetType: 'ais.dynamicWidgets';
@@ -28,7 +28,7 @@ interface Marker {
28
28
  };
29
29
  latLng: google.maps.LatLng;
30
30
  element: HTMLDivElement;
31
- getPosition(): google.maps.LatLng;
31
+ getPosition: () => google.maps.LatLng;
32
32
  }
33
33
  declare const createHTMLMarker: (googleReference: typeof google) => new (args: HTMLMarkerArguments) => google.maps.OverlayView & Marker;
34
34
  export default createHTMLMarker;
@@ -44,7 +44,7 @@ export type GeoSearchMarker<TOptions> = {
44
44
  * See the documentation for more information:
45
45
  * https://developers.google.com/maps/documentation/javascript/reference/3/#MarkerOptions
46
46
  */
47
- createOptions?(item: GeoHit): TOptions;
47
+ createOptions?: (item: GeoHit) => TOptions;
48
48
  /**
49
49
  * Object that takes an event type (ex: `click`, `mouseover`) as key and a
50
50
  * listener as value. The listener is provided with an object that contains: