react-instantsearch-core 7.16.0 → 7.16.2

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.
@@ -14,8 +14,9 @@ var _useInstantSearchServerContext = require("../lib/useInstantSearchServerConte
14
14
  var _useInstantSearchSSRContext = require("../lib/useInstantSearchSSRContext");
15
15
  var _useStableValue = require("../lib/useStableValue");
16
16
  var _useWidget = require("../lib/useWidget");
17
- var _excluded = ["instantSearchInstance", "widgetParams"],
18
- _excluded2 = ["widgetParams"];
17
+ var _excluded = ["skipSuspense"],
18
+ _excluded2 = ["instantSearchInstance", "widgetParams"],
19
+ _excluded3 = ["widgetParams"];
19
20
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
20
21
  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."); }
21
22
  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); }
@@ -31,7 +32,10 @@ function _objectWithoutProperties(source, excluded) { if (source == null) return
31
32
  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; }
32
33
  function useConnector(connector) {
33
34
  var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
34
- var additionalWidgetProperties = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
35
+ var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
36
+ _ref$skipSuspense = _ref.skipSuspense,
37
+ skipSuspense = _ref$skipSuspense === void 0 ? false : _ref$skipSuspense,
38
+ additionalWidgetProperties = _objectWithoutProperties(_ref, _excluded);
35
39
  var serverContext = (0, _useInstantSearchServerContext.useInstantSearchServerContext)();
36
40
  var ssrContext = (0, _useInstantSearchSSRContext.useInstantSearchSSRContext)();
37
41
  var search = (0, _useInstantSearchContext.useInstantSearchContext)();
@@ -65,7 +69,7 @@ function useConnector(connector) {
65
69
  if (shouldSetStateRef.current) {
66
70
  var instantSearchInstance = connectorState.instantSearchInstance,
67
71
  widgetParams = connectorState.widgetParams,
68
- renderState = _objectWithoutProperties(connectorState, _excluded);
72
+ renderState = _objectWithoutProperties(connectorState, _excluded2);
69
73
 
70
74
  // We only update the state when a widget render state param changes,
71
75
  // except for functions. We ignore function reference changes to avoid
@@ -121,7 +125,7 @@ function useConnector(connector) {
121
125
  error: search.error
122
126
  }),
123
127
  widgetParams = _widget$getWidgetRend.widgetParams,
124
- renderState = _objectWithoutProperties(_widget$getWidgetRend, _excluded2);
128
+ renderState = _objectWithoutProperties(_widget$getWidgetRend, _excluded3);
125
129
  return renderState;
126
130
  }
127
131
  return {};
@@ -133,7 +137,8 @@ function useConnector(connector) {
133
137
  widget: widget,
134
138
  parentIndex: parentIndex,
135
139
  props: stableProps,
136
- shouldSsr: Boolean(serverContext)
140
+ shouldSsr: Boolean(serverContext),
141
+ skipSuspense: skipSuspense
137
142
  });
138
143
  return state;
139
144
  }
package/dist/cjs/index.js CHANGED
@@ -457,6 +457,18 @@ Object.keys(_InstantSearchRSCContext).forEach(function (key) {
457
457
  }
458
458
  });
459
459
  });
460
+ var _InstantSearchSSRContext = require("./lib/InstantSearchSSRContext");
461
+ Object.keys(_InstantSearchSSRContext).forEach(function (key) {
462
+ if (key === "default" || key === "__esModule") return;
463
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
464
+ if (key in exports && exports[key] === _InstantSearchSSRContext[key]) return;
465
+ Object.defineProperty(exports, key, {
466
+ enumerable: true,
467
+ get: function get() {
468
+ return _InstantSearchSSRContext[key];
469
+ }
470
+ });
471
+ });
460
472
  var _server = require("./server");
461
473
  Object.keys(_server).forEach(function (key) {
462
474
  if (key === "default" || key === "__esModule") return;
@@ -5,4 +5,10 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.InstantSearchRSCContext = void 0;
7
7
  var _react = require("react");
8
- var InstantSearchRSCContext = exports.InstantSearchRSCContext = /*#__PURE__*/(0, _react.createContext)(null);
8
+ var InstantSearchRSCContext = exports.InstantSearchRSCContext = /*#__PURE__*/(0, _react.createContext)({
9
+ countRef: {
10
+ current: 0
11
+ },
12
+ waitForResultsRef: null,
13
+ ignoreMultipleHooksWarning: false
14
+ });
@@ -32,7 +32,8 @@ function useIndex(props) {
32
32
  widget: indexWidget,
33
33
  parentIndex: parentIndex,
34
34
  props: stableProps,
35
- shouldSsr: Boolean(serverContext || initialResults)
35
+ shouldSsr: Boolean(serverContext || initialResults),
36
+ skipSuspense: true
36
37
  });
37
38
  return indexWidget;
38
39
  }
@@ -12,7 +12,7 @@ var _dequal = require("./dequal");
12
12
  var _useForceUpdate = require("./useForceUpdate");
13
13
  var _useInstantSearchServerContext = require("./useInstantSearchServerContext");
14
14
  var _useInstantSearchSSRContext = require("./useInstantSearchSSRContext");
15
- var _useRSCContext = require("./useRSCContext");
15
+ var _useRSCContext2 = require("./useRSCContext");
16
16
  var _warn = require("./warn");
17
17
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18
18
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
@@ -32,15 +32,16 @@ function useInstantSearchApi(props) {
32
32
  var forceUpdate = (0, _useForceUpdate.useForceUpdate)();
33
33
  var serverContext = (0, _useInstantSearchServerContext.useInstantSearchServerContext)();
34
34
  var serverState = (0, _useInstantSearchSSRContext.useInstantSearchSSRContext)();
35
- var waitingForResultsRef = (0, _useRSCContext.useRSCContext)();
35
+ var _useRSCContext = (0, _useRSCContext2.useRSCContext)(),
36
+ waitForResultsRef = _useRSCContext.waitForResultsRef;
36
37
  var initialResults = serverState === null || serverState === void 0 ? void 0 : serverState.initialResults;
37
38
  var prevPropsRef = (0, _react.useRef)(props);
38
- var shouldRenderAtOnce = serverContext || initialResults || waitingForResultsRef;
39
+ var shouldRenderAtOnce = serverContext || initialResults || waitForResultsRef;
39
40
  var searchRef = (0, _react.useRef)(null);
40
41
  // As we need to render on mount with SSR, using the local ref above in `StrictMode` will
41
42
  // create and start two instances of InstantSearch. To avoid this, we instead discard it and use
42
43
  // an upward ref from `InstantSearchSSRContext` as it has already been mounted a second time at this point.
43
- if (serverState) {
44
+ if (serverState !== null && serverState !== void 0 && serverState.ssrSearchRef) {
44
45
  searchRef = serverState.ssrSearchRef;
45
46
  }
46
47
  if (searchRef.current === null) {
@@ -88,7 +89,7 @@ function useInstantSearchApi(props) {
88
89
  });
89
90
  }
90
91
  warnNextRouter(props.routing);
91
- warnNextAppDir(Boolean(waitingForResultsRef));
92
+ warnNextAppDir(Boolean(waitForResultsRef));
92
93
  searchRef.current = search;
93
94
  }
94
95
  {
@@ -155,6 +156,9 @@ function useInstantSearchApi(props) {
155
156
  search._preventWidgetCleanup = false;
156
157
  }
157
158
  return function () {
159
+ if (serverState !== null && serverState !== void 0 && serverState.ssrSearchRef) {
160
+ return;
161
+ }
158
162
  function cleanup() {
159
163
  search.dispose();
160
164
  }
@@ -166,13 +170,12 @@ function useInstantSearchApi(props) {
166
170
  // in the next effect.
167
171
  // (There might be better ways to do this.)
168
172
  cleanupTimerRef.current = setTimeout(cleanup);
169
-
170
173
  // We need to prevent the `useWidget` cleanup function so that widgets
171
174
  // are not removed before the instance is disposed, triggering
172
175
  // an unwanted search request.
173
176
  search._preventWidgetCleanup = true;
174
177
  };
175
- }, [forceUpdate]), function () {
178
+ }, [forceUpdate, serverState]), function () {
176
179
  return searchRef.current;
177
180
  }, function () {
178
181
  return searchRef.current;
@@ -204,7 +207,7 @@ function warnNextAppDir(isRscContextDefined) {
204
207
  if (!(process.env.NODE_ENV === 'development') || typeof window === 'undefined' || isRscContextDefined) {
205
208
  return;
206
209
  }
207
- process.env.NODE_ENV === 'development' ? (0, _warn.warn)(Boolean((_next = window.next) === null || _next === void 0 ? void 0 : _next.appDir) === false, "\nWe've detected you are using Next.js with the App Router.\nWe released an **experimental** package called \"react-instantsearch-nextjs\" that makes SSR work with the App Router.\nPlease check its usage instructions: https://www.algolia.com/doc/guides/building-search-ui/going-further/server-side-rendering/react/#with-nextjs\n\nThis warning will not be outputted in production builds.") : void 0;
210
+ process.env.NODE_ENV === 'development' ? (0, _warn.warn)(Boolean((_next = window.next) === null || _next === void 0 ? void 0 : _next.appDir) === false, "\nWe've detected you are using Next.js with the App Router.\nWe released a package called \"react-instantsearch-nextjs\" that makes SSR work with the App Router.\nPlease check its usage instructions: https://www.algolia.com/doc/guides/building-search-ui/going-further/server-side-rendering/react/#with-nextjs-app-router\n\nThis warning will not be outputted in production builds.") : void 0;
208
211
  }
209
212
 
210
213
  /**
@@ -9,14 +9,19 @@ var _dequal = require("./dequal");
9
9
  var _use = require("./use");
10
10
  var _useInstantSearchContext = require("./useInstantSearchContext");
11
11
  var _useIsomorphicLayoutEffect = require("./useIsomorphicLayoutEffect");
12
- var _useRSCContext = require("./useRSCContext");
12
+ var _useRSCContext2 = require("./useRSCContext");
13
+ var _warn = require("./warn");
13
14
  function useWidget(_ref) {
14
- var _waitingForResultsRef;
15
+ var _waitForResultsRef$cu, _waitForResultsRef$cu2;
15
16
  var widget = _ref.widget,
16
17
  parentIndex = _ref.parentIndex,
17
18
  props = _ref.props,
18
- shouldSsr = _ref.shouldSsr;
19
- var waitingForResultsRef = (0, _useRSCContext.useRSCContext)();
19
+ shouldSsr = _ref.shouldSsr,
20
+ skipSuspense = _ref.skipSuspense;
21
+ var _useRSCContext = (0, _useRSCContext2.useRSCContext)(),
22
+ waitForResultsRef = _useRSCContext.waitForResultsRef,
23
+ countRef = _useRSCContext.countRef,
24
+ ignoreMultipleHooksWarning = _useRSCContext.ignoreMultipleHooksWarning;
20
25
  var prevPropsRef = (0, _react.useRef)(props);
21
26
  (0, _react.useEffect)(function () {
22
27
  prevPropsRef.current = props;
@@ -76,18 +81,20 @@ function useWidget(_ref) {
76
81
  });
77
82
  };
78
83
  }, [parentIndex, widget, shouldSsr, search, props]);
79
- if (shouldAddWidgetEarly || (waitingForResultsRef === null || waitingForResultsRef === void 0 ? void 0 : (_waitingForResultsRef = waitingForResultsRef.current) === null || _waitingForResultsRef === void 0 ? void 0 : _waitingForResultsRef.status) === 'pending') {
84
+ if (shouldAddWidgetEarly || (waitForResultsRef === null || waitForResultsRef === void 0 ? void 0 : (_waitForResultsRef$cu = waitForResultsRef.current) === null || _waitForResultsRef$cu === void 0 ? void 0 : _waitForResultsRef$cu.status) === 'pending') {
80
85
  parentIndex.addWidgets([widget]);
81
86
  }
82
- if (typeof window === 'undefined' && waitingForResultsRef !== null && waitingForResultsRef !== void 0 && waitingForResultsRef.current &&
83
- // We need the widgets contained in the index to be added before we trigger the search request.
84
- widget.$$type !== 'ais.index') {
87
+ if (waitForResultsRef !== null && waitForResultsRef !== void 0 && waitForResultsRef.current && !skipSuspense) {
85
88
  var _search$helper;
86
- (0, _use.use)(waitingForResultsRef.current);
89
+ (0, _use.use)(waitForResultsRef.current);
87
90
  // If we made a second request because of DynamicWidgets, we need to wait for the second result,
88
91
  // except for DynamicWidgets itself which needs to render its children after the first result.
89
92
  if (widget.$$type !== 'ais.dynamicWidgets' && (_search$helper = search.helper) !== null && _search$helper !== void 0 && _search$helper.lastResults) {
90
- (0, _use.use)(waitingForResultsRef.current);
93
+ (0, _use.use)(waitForResultsRef.current);
91
94
  }
92
95
  }
96
+ if ((waitForResultsRef === null || waitForResultsRef === void 0 ? void 0 : (_waitForResultsRef$cu2 = waitForResultsRef.current) === null || _waitForResultsRef$cu2 === void 0 ? void 0 : _waitForResultsRef$cu2.status) === 'fulfilled') {
97
+ countRef.current += 1;
98
+ process.env.NODE_ENV === 'development' ? (0, _warn.warn)(countRef.current > parentIndex.getWidgets().length && !ignoreMultipleHooksWarning, "We detected you may have a component with multiple InstantSearch hooks.\n\nWith Next.js, you need to set `skipSuspense` to `true` for all but the last hook in the component, otherwise, only the first hook will be rendered on the server.\n\nThis warning can be a false positive if you are using dynamic widgets or multi-index, in which case you can ignore it by setting `ignoreMultipleHooksWarning` to `true` in `<InstantSearchNext`.\n\nFor more information, see https://www.algolia.com/doc/guides/building-search-ui/going-further/server-side-rendering/react/#composing-hooks") : void 0;
99
+ }
93
100
  }
@@ -4,4 +4,4 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _default = exports.default = '7.16.0';
7
+ var _default = exports.default = '7.16.2';
@@ -1,3 +1,5 @@
1
1
  import type { Connector, Widget, WidgetDescription } from 'instantsearch.js';
2
- export type AdditionalWidgetProperties = Partial<Widget<WidgetDescription>>;
3
- export declare function useConnector<TProps extends Record<string, unknown>, TDescription extends WidgetDescription>(connector: Connector<TDescription, TProps>, props?: TProps, additionalWidgetProperties?: AdditionalWidgetProperties): TDescription['renderState'];
2
+ export type AdditionalWidgetProperties = Partial<Widget<WidgetDescription>> & {
3
+ skipSuspense?: boolean;
4
+ };
5
+ export declare function useConnector<TProps extends Record<string, unknown>, TDescription extends WidgetDescription>(connector: Connector<TDescription, TProps>, props?: TProps, { skipSuspense, ...additionalWidgetProperties }?: AdditionalWidgetProperties): TDescription['renderState'];
@@ -1,6 +1,7 @@
1
1
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
- var _excluded = ["instantSearchInstance", "widgetParams"],
3
- _excluded2 = ["widgetParams"];
2
+ var _excluded = ["skipSuspense"],
3
+ _excluded2 = ["instantSearchInstance", "widgetParams"],
4
+ _excluded3 = ["widgetParams"];
4
5
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
5
6
  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."); }
6
7
  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); }
@@ -25,7 +26,10 @@ import { useStableValue } from "../lib/useStableValue.js";
25
26
  import { useWidget } from "../lib/useWidget.js";
26
27
  export function useConnector(connector) {
27
28
  var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
28
- var additionalWidgetProperties = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
29
+ var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
30
+ _ref$skipSuspense = _ref.skipSuspense,
31
+ skipSuspense = _ref$skipSuspense === void 0 ? false : _ref$skipSuspense,
32
+ additionalWidgetProperties = _objectWithoutProperties(_ref, _excluded);
29
33
  var serverContext = useInstantSearchServerContext();
30
34
  var ssrContext = useInstantSearchSSRContext();
31
35
  var search = useInstantSearchContext();
@@ -59,7 +63,7 @@ export function useConnector(connector) {
59
63
  if (shouldSetStateRef.current) {
60
64
  var instantSearchInstance = connectorState.instantSearchInstance,
61
65
  widgetParams = connectorState.widgetParams,
62
- renderState = _objectWithoutProperties(connectorState, _excluded);
66
+ renderState = _objectWithoutProperties(connectorState, _excluded2);
63
67
 
64
68
  // We only update the state when a widget render state param changes,
65
69
  // except for functions. We ignore function reference changes to avoid
@@ -115,7 +119,7 @@ export function useConnector(connector) {
115
119
  error: search.error
116
120
  }),
117
121
  widgetParams = _widget$getWidgetRend.widgetParams,
118
- renderState = _objectWithoutProperties(_widget$getWidgetRend, _excluded2);
122
+ renderState = _objectWithoutProperties(_widget$getWidgetRend, _excluded3);
119
123
  return renderState;
120
124
  }
121
125
  return {};
@@ -127,7 +131,8 @@ export function useConnector(connector) {
127
131
  widget: widget,
128
132
  parentIndex: parentIndex,
129
133
  props: stableProps,
130
- shouldSsr: Boolean(serverContext)
134
+ shouldSsr: Boolean(serverContext),
135
+ skipSuspense: skipSuspense
131
136
  });
132
137
  return state;
133
138
  }
@@ -36,4 +36,5 @@ export * from './lib/wrapPromiseWithState';
36
36
  export * from './lib/useInstantSearchContext';
37
37
  export * from './lib/useRSCContext';
38
38
  export * from './lib/InstantSearchRSCContext';
39
+ export * from './lib/InstantSearchSSRContext';
39
40
  export * from './server';
package/dist/es/index.js CHANGED
@@ -36,4 +36,5 @@ export * from "./lib/wrapPromiseWithState.js";
36
36
  export * from "./lib/useInstantSearchContext.js";
37
37
  export * from "./lib/useRSCContext.js";
38
38
  export * from "./lib/InstantSearchRSCContext.js";
39
+ export * from "./lib/InstantSearchSSRContext.js";
39
40
  export * from "./server/index.js";
@@ -1,4 +1,8 @@
1
1
  import type { PromiseWithState } from './wrapPromiseWithState';
2
- import type { MutableRefObject } from 'react';
3
- export type InstantSearchRSCContextApi = MutableRefObject<PromiseWithState<void> | null> | null;
2
+ import type { RefObject } from 'react';
3
+ export type InstantSearchRSCContextApi = {
4
+ waitForResultsRef: RefObject<PromiseWithState<void> | null> | null;
5
+ countRef: RefObject<number>;
6
+ ignoreMultipleHooksWarning: boolean;
7
+ };
4
8
  export declare const InstantSearchRSCContext: import("react").Context<InstantSearchRSCContextApi>;
@@ -1,2 +1,8 @@
1
1
  import { createContext } from 'react';
2
- export var InstantSearchRSCContext = /*#__PURE__*/createContext(null);
2
+ export var InstantSearchRSCContext = /*#__PURE__*/createContext({
3
+ countRef: {
4
+ current: 0
5
+ },
6
+ waitForResultsRef: null,
7
+ ignoreMultipleHooksWarning: false
8
+ });
@@ -25,7 +25,8 @@ export function useIndex(props) {
25
25
  widget: indexWidget,
26
26
  parentIndex: parentIndex,
27
27
  props: stableProps,
28
- shouldSsr: Boolean(serverContext || initialResults)
28
+ shouldSsr: Boolean(serverContext || initialResults),
29
+ skipSuspense: true
29
30
  });
30
31
  return indexWidget;
31
32
  }
@@ -23,15 +23,16 @@ export function useInstantSearchApi(props) {
23
23
  var forceUpdate = useForceUpdate();
24
24
  var serverContext = useInstantSearchServerContext();
25
25
  var serverState = useInstantSearchSSRContext();
26
- var waitingForResultsRef = useRSCContext();
26
+ var _useRSCContext = useRSCContext(),
27
+ waitForResultsRef = _useRSCContext.waitForResultsRef;
27
28
  var initialResults = serverState === null || serverState === void 0 ? void 0 : serverState.initialResults;
28
29
  var prevPropsRef = useRef(props);
29
- var shouldRenderAtOnce = serverContext || initialResults || waitingForResultsRef;
30
+ var shouldRenderAtOnce = serverContext || initialResults || waitForResultsRef;
30
31
  var searchRef = useRef(null);
31
32
  // As we need to render on mount with SSR, using the local ref above in `StrictMode` will
32
33
  // create and start two instances of InstantSearch. To avoid this, we instead discard it and use
33
34
  // an upward ref from `InstantSearchSSRContext` as it has already been mounted a second time at this point.
34
- if (serverState) {
35
+ if (serverState !== null && serverState !== void 0 && serverState.ssrSearchRef) {
35
36
  searchRef = serverState.ssrSearchRef;
36
37
  }
37
38
  if (searchRef.current === null) {
@@ -79,7 +80,7 @@ export function useInstantSearchApi(props) {
79
80
  });
80
81
  }
81
82
  warnNextRouter(props.routing);
82
- warnNextAppDir(Boolean(waitingForResultsRef));
83
+ warnNextAppDir(Boolean(waitForResultsRef));
83
84
  searchRef.current = search;
84
85
  }
85
86
  {
@@ -146,6 +147,9 @@ export function useInstantSearchApi(props) {
146
147
  search._preventWidgetCleanup = false;
147
148
  }
148
149
  return function () {
150
+ if (serverState !== null && serverState !== void 0 && serverState.ssrSearchRef) {
151
+ return;
152
+ }
149
153
  function cleanup() {
150
154
  search.dispose();
151
155
  }
@@ -157,13 +161,12 @@ export function useInstantSearchApi(props) {
157
161
  // in the next effect.
158
162
  // (There might be better ways to do this.)
159
163
  cleanupTimerRef.current = setTimeout(cleanup);
160
-
161
164
  // We need to prevent the `useWidget` cleanup function so that widgets
162
165
  // are not removed before the instance is disposed, triggering
163
166
  // an unwanted search request.
164
167
  search._preventWidgetCleanup = true;
165
168
  };
166
- }, [forceUpdate]), function () {
169
+ }, [forceUpdate, serverState]), function () {
167
170
  return searchRef.current;
168
171
  }, function () {
169
172
  return searchRef.current;
@@ -195,7 +198,7 @@ function warnNextAppDir(isRscContextDefined) {
195
198
  if (!(process.env.NODE_ENV === 'development') || typeof window === 'undefined' || isRscContextDefined) {
196
199
  return;
197
200
  }
198
- process.env.NODE_ENV === 'development' ? warn(Boolean((_next = window.next) === null || _next === void 0 ? void 0 : _next.appDir) === false, "\nWe've detected you are using Next.js with the App Router.\nWe released an **experimental** package called \"react-instantsearch-nextjs\" that makes SSR work with the App Router.\nPlease check its usage instructions: https://www.algolia.com/doc/guides/building-search-ui/going-further/server-side-rendering/react/#with-nextjs\n\nThis warning will not be outputted in production builds.") : void 0;
201
+ process.env.NODE_ENV === 'development' ? warn(Boolean((_next = window.next) === null || _next === void 0 ? void 0 : _next.appDir) === false, "\nWe've detected you are using Next.js with the App Router.\nWe released a package called \"react-instantsearch-nextjs\" that makes SSR work with the App Router.\nPlease check its usage instructions: https://www.algolia.com/doc/guides/building-search-ui/going-further/server-side-rendering/react/#with-nextjs-app-router\n\nThis warning will not be outputted in production builds.") : void 0;
199
202
  }
200
203
 
201
204
  /**
@@ -1,8 +1,9 @@
1
1
  import type { Widget } from 'instantsearch.js';
2
2
  import type { IndexWidget } from 'instantsearch.js/es/widgets/index/index';
3
- export declare function useWidget<TWidget extends Widget | IndexWidget, TProps>({ widget, parentIndex, props, shouldSsr, }: {
3
+ export declare function useWidget<TWidget extends Widget | IndexWidget, TProps>({ widget, parentIndex, props, shouldSsr, skipSuspense, }: {
4
4
  widget: TWidget;
5
5
  parentIndex: IndexWidget;
6
6
  props: TProps;
7
7
  shouldSsr: boolean;
8
+ skipSuspense: boolean;
8
9
  }): void;
@@ -4,13 +4,18 @@ import { use } from "./use.js";
4
4
  import { useInstantSearchContext } from "./useInstantSearchContext.js";
5
5
  import { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect.js";
6
6
  import { useRSCContext } from "./useRSCContext.js";
7
+ import { warn } from "./warn.js";
7
8
  export function useWidget(_ref) {
8
- var _waitingForResultsRef;
9
+ var _waitForResultsRef$cu, _waitForResultsRef$cu2;
9
10
  var widget = _ref.widget,
10
11
  parentIndex = _ref.parentIndex,
11
12
  props = _ref.props,
12
- shouldSsr = _ref.shouldSsr;
13
- var waitingForResultsRef = useRSCContext();
13
+ shouldSsr = _ref.shouldSsr,
14
+ skipSuspense = _ref.skipSuspense;
15
+ var _useRSCContext = useRSCContext(),
16
+ waitForResultsRef = _useRSCContext.waitForResultsRef,
17
+ countRef = _useRSCContext.countRef,
18
+ ignoreMultipleHooksWarning = _useRSCContext.ignoreMultipleHooksWarning;
14
19
  var prevPropsRef = useRef(props);
15
20
  useEffect(function () {
16
21
  prevPropsRef.current = props;
@@ -70,18 +75,20 @@ export function useWidget(_ref) {
70
75
  });
71
76
  };
72
77
  }, [parentIndex, widget, shouldSsr, search, props]);
73
- if (shouldAddWidgetEarly || (waitingForResultsRef === null || waitingForResultsRef === void 0 ? void 0 : (_waitingForResultsRef = waitingForResultsRef.current) === null || _waitingForResultsRef === void 0 ? void 0 : _waitingForResultsRef.status) === 'pending') {
78
+ if (shouldAddWidgetEarly || (waitForResultsRef === null || waitForResultsRef === void 0 ? void 0 : (_waitForResultsRef$cu = waitForResultsRef.current) === null || _waitForResultsRef$cu === void 0 ? void 0 : _waitForResultsRef$cu.status) === 'pending') {
74
79
  parentIndex.addWidgets([widget]);
75
80
  }
76
- if (typeof window === 'undefined' && waitingForResultsRef !== null && waitingForResultsRef !== void 0 && waitingForResultsRef.current &&
77
- // We need the widgets contained in the index to be added before we trigger the search request.
78
- widget.$$type !== 'ais.index') {
81
+ if (waitForResultsRef !== null && waitForResultsRef !== void 0 && waitForResultsRef.current && !skipSuspense) {
79
82
  var _search$helper;
80
- use(waitingForResultsRef.current);
83
+ use(waitForResultsRef.current);
81
84
  // If we made a second request because of DynamicWidgets, we need to wait for the second result,
82
85
  // except for DynamicWidgets itself which needs to render its children after the first result.
83
86
  if (widget.$$type !== 'ais.dynamicWidgets' && (_search$helper = search.helper) !== null && _search$helper !== void 0 && _search$helper.lastResults) {
84
- use(waitingForResultsRef.current);
87
+ use(waitForResultsRef.current);
85
88
  }
86
89
  }
90
+ if ((waitForResultsRef === null || waitForResultsRef === void 0 ? void 0 : (_waitForResultsRef$cu2 = waitForResultsRef.current) === null || _waitForResultsRef$cu2 === void 0 ? void 0 : _waitForResultsRef$cu2.status) === 'fulfilled') {
91
+ countRef.current += 1;
92
+ process.env.NODE_ENV === 'development' ? warn(countRef.current > parentIndex.getWidgets().length && !ignoreMultipleHooksWarning, "We detected you may have a component with multiple InstantSearch hooks.\n\nWith Next.js, you need to set `skipSuspense` to `true` for all but the last hook in the component, otherwise, only the first hook will be rendered on the server.\n\nThis warning can be a false positive if you are using dynamic widgets or multi-index, in which case you can ignore it by setting `ignoreMultipleHooksWarning` to `true` in `<InstantSearchNext`.\n\nFor more information, see https://www.algolia.com/doc/guides/building-search-ui/going-further/server-side-rendering/react/#composing-hooks") : void 0;
93
+ }
87
94
  }
@@ -1,2 +1,2 @@
1
- declare const _default: "7.16.0";
1
+ declare const _default: "7.16.2";
2
2
  export default _default;
@@ -1 +1 @@
1
- export default '7.16.0';
1
+ export default '7.16.2';