react-instantsearch-core 7.47.0 → 7.48.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.
@@ -9,4 +9,4 @@ Object.defineProperty(exports, "default", {
9
9
  return _default;
10
10
  }
11
11
  });
12
- var _default = '7.47.0';
12
+ var _default = '7.48.0';
@@ -1,2 +1,2 @@
1
- declare const _default: "7.47.0";
1
+ declare const _default: "7.48.0";
2
2
  export default _default;
@@ -1,3 +1,3 @@
1
- var version = '7.47.0';
1
+ var version = '7.48.0';
2
2
 
3
3
  export { version as default };
@@ -1,4 +1,4 @@
1
- /*! React InstantSearch Core 7.47.0 | © Algolia, Inc. and contributors; MIT License | https://github.com/algolia/instantsearch */
1
+ /*! React InstantSearch Core 7.48.0 | © Algolia, Inc. and contributors; MIT License | https://github.com/algolia/instantsearch */
2
2
  (function (global, factory) {
3
3
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) :
4
4
  typeof define === 'function' && define.amd ? define(['exports', 'react'], factory) :
@@ -24,7 +24,7 @@
24
24
 
25
25
  var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
26
26
 
27
- var version$2 = '7.47.0';
27
+ var version$2 = '7.48.0';
28
28
 
29
29
  function _define_property(obj, key, value) {
30
30
  if (key in obj) {
@@ -9418,7 +9418,7 @@
9418
9418
  });
9419
9419
  }
9420
9420
 
9421
- var version = '4.114.0';
9421
+ var version = '4.115.0';
9422
9422
 
9423
9423
  var ANONYMOUS_TOKEN_COOKIE_KEY = '_ALGOLIA';
9424
9424
  function getCookie(name) {
@@ -16061,6 +16061,36 @@
16061
16061
  return typeof s === 'string';
16062
16062
  });
16063
16063
  }
16064
+ // Key order is not significant to the request, so a plain `JSON.stringify` would
16065
+ // report two identical payloads as different.
16066
+ function stableKey(value) {
16067
+ if (value === null || (typeof value === "undefined" ? "undefined" : _type_of(value)) !== 'object') {
16068
+ var _JSON_stringify;
16069
+ return (_JSON_stringify = JSON.stringify(value)) !== null && _JSON_stringify !== void 0 ? _JSON_stringify : 'null';
16070
+ }
16071
+ if (Array.isArray(value)) {
16072
+ return "[".concat(value.map(stableKey).join(','), "]");
16073
+ }
16074
+ var record = value;
16075
+ return "{".concat(Object.keys(record).sort().map(function(key) {
16076
+ return "".concat(JSON.stringify(key), ":").concat(stableKey(record[key]));
16077
+ }).join(','), "}");
16078
+ }
16079
+ /**
16080
+ * Comparable identity of a task payload, or `null` when it cannot be compared.
16081
+ */ function taskPayloadKey(payload) {
16082
+ try {
16083
+ // Round-trip first so the comparison sees what the request will actually
16084
+ // carry: `JSON.stringify` applies `toJSON` (a `Date` becomes its ISO string)
16085
+ // and drops the values the wire drops. Walking the raw object instead would
16086
+ // read a `Date` as a key-less object and call two different instants equal.
16087
+ return stableKey(JSON.parse(JSON.stringify(payload)));
16088
+ } catch (unused) {
16089
+ // Circular or otherwise unserializable. Never claim a match on a payload we
16090
+ // could not read; let the request go out and fail where it does today.
16091
+ return null;
16092
+ }
16093
+ }
16064
16094
  function buildSuggestionMessage(suggestion) {
16065
16095
  return "The user clicked this on-page suggestion. Use the current page context first, then search only if needed.\n\nSuggestion: ".concat(suggestion);
16066
16096
  }
@@ -16128,6 +16158,10 @@
16128
16158
  var error;
16129
16159
  var debounceTimer;
16130
16160
  var lastStateSignature = null;
16161
+ // The payload of the last request that was actually sent. The automatic
16162
+ // trigger keys on the search state, which is only a proxy for the payload,
16163
+ // so this is what decides whether a request would ask anything new.
16164
+ var lastSubmittedPayload = null;
16131
16165
  var latestRenderOptions = null;
16132
16166
  // Set in `dispose()`. A debounced or in-flight `fetch()` can resolve after
16133
16167
  // the widget is unmounted; this guard stops those late callbacks from
@@ -16138,6 +16172,10 @@
16138
16172
  // still-in-flight request from the previous state must not paint its
16139
16173
  // suggestions, its inner render is ignored until the new `submit` starts.
16140
16174
  var refetchPending = false;
16175
+ // True when `refetchPending` made an inner render be dropped. The fetch
16176
+ // that dropped it was expected to render in its place; if that fetch turns
16177
+ // out to send nothing, it has to reconcile the dropped state instead.
16178
+ var droppedInnerRender = false;
16141
16179
  var getStateSignature = function getStateSignature(results) {
16142
16180
  var _buildFilters;
16143
16181
  if (results.queryID) {
@@ -16224,19 +16262,62 @@
16224
16262
  instantSearchInstance: renderOptions.instantSearchInstance
16225
16263
  }), false);
16226
16264
  };
16265
+ // Copies an inner render's state into this widget's and re-renders on the
16266
+ // client.
16267
+ var adoptInnerState = function adoptInnerState(renderState) {
16268
+ error = renderState.error;
16269
+ if (renderState.error) {
16270
+ // A failed task (including a mid-stream `error` event) must not leave
16271
+ // any streamed partial visible.
16272
+ suggestions = [];
16273
+ } else if (renderState.isLoading || renderState.output !== undefined) {
16274
+ // Only adopt the inner output once a request is loading or has
16275
+ // produced one, so the initial no-op render doesn't clobber pills.
16276
+ suggestions = parseSuggestions(renderState.output);
16277
+ }
16278
+ isLoading = renderState.isLoading;
16279
+ if (!latestRenderOptions) return;
16280
+ renderOutward(latestRenderOptions);
16281
+ };
16227
16282
  var fetchAndRender = function fetchAndRender(results, renderOptions) {
16283
+ var _ref = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {}, _ref_force = _ref.force, force = _ref_force === void 0 ? false : _ref_force;
16228
16284
  var _results_hits;
16229
16285
  if (disposed || !tasksState) return;
16286
+ var hadDroppedInnerRender = droppedInnerRender;
16230
16287
  refetchPending = false;
16288
+ droppedInnerRender = false;
16231
16289
  var hasContext = context !== undefined;
16232
16290
  if (!hasContext && !(results === null || results === void 0 ? void 0 : (_results_hits = results.hits) === null || _results_hits === void 0 ? void 0 : _results_hits.length)) {
16233
16291
  tasksState.invalidate();
16234
16292
  suggestions = [];
16235
16293
  isLoading = false;
16294
+ // The output is gone, so the same payload must be allowed to rebuild it.
16295
+ lastSubmittedPayload = null;
16236
16296
  renderOutward(renderOptions);
16237
16297
  return;
16238
16298
  }
16239
- tasksState.submit(buildInput(results));
16299
+ var input = buildInput(results);
16300
+ var payload = taskPayloadKey(input);
16301
+ // A moved search state does not always mean a different question: with an
16302
+ // explicit `context` the payload ignores the results entirely, so a new
16303
+ // `queryID` or a new hit order produces a byte-identical request. Sending
16304
+ // it again spends a model call on an answer already on screen. Leave the
16305
+ // current suggestions alone and send nothing. `force` is the explicit
16306
+ // path (`refresh()`), which must always reach the network.
16307
+ if (!force && payload !== null && payload === lastSubmittedPayload) {
16308
+ // Nothing goes out, so nothing will render — but the state change that
16309
+ // scheduled this fetch also made `handleInnerRender` drop the render
16310
+ // that was carrying the previous request's result. Reconcile it here or
16311
+ // the widget keeps that request's `isLoading: true` with no
16312
+ // suggestions, and nothing later clears it: `refresh()` is blocked by
16313
+ // its own `isLoading` guard and an unchanged payload keeps skipping.
16314
+ if (hadDroppedInnerRender) {
16315
+ adoptInnerState(tasksState);
16316
+ }
16317
+ return;
16318
+ }
16319
+ lastSubmittedPayload = payload;
16320
+ tasksState.submit(input);
16240
16321
  };
16241
16322
  var refresh = function refresh() {
16242
16323
  if (isLoading) return;
@@ -16244,7 +16325,9 @@
16244
16325
  if (!results || !latestRenderOptions) return;
16245
16326
  clearTimeout(debounceTimer);
16246
16327
  lastStateSignature = getStateSignature(results);
16247
- fetchAndRender(results, latestRenderOptions);
16328
+ fetchAndRender(results, latestRenderOptions, {
16329
+ force: true
16330
+ });
16248
16331
  };
16249
16332
  var getWidgetRenderState = function getWidgetRenderState(renderOptions) {
16250
16333
  var results = 'results' in renderOptions ? renderOptions.results : undefined;
@@ -16270,20 +16353,18 @@
16270
16353
  // resolve/error) into this widget's state and re-renders on the client.
16271
16354
  var handleInnerRender = function handleInnerRender(renderState) {
16272
16355
  tasksState = renderState;
16273
- if (refetchPending) return;
16274
- error = renderState.error;
16275
16356
  if (renderState.error) {
16276
- // A failed task (including a mid-stream `error` event) must not leave
16277
- // any streamed partial visible.
16278
- suggestions = [];
16279
- } else if (renderState.isLoading || renderState.output !== undefined) {
16280
- // Only adopt the inner output once a request is loading or has
16281
- // produced one, so the initial no-op render doesn't clobber pills.
16282
- suggestions = parseSuggestions(renderState.output);
16357
+ // Keep a failed payload retryable: without this the next automatic
16358
+ // attempt with the same payload would be skipped as a duplicate and
16359
+ // the error would have no way to clear. Set before the `refetchPending`
16360
+ // return so a failure that lands mid-refetch is not swallowed.
16361
+ lastSubmittedPayload = null;
16362
+ }
16363
+ if (refetchPending) {
16364
+ droppedInnerRender = true;
16365
+ return;
16283
16366
  }
16284
- isLoading = renderState.isLoading;
16285
- if (!latestRenderOptions) return;
16286
- renderOutward(latestRenderOptions);
16367
+ adoptInnerState(renderState);
16287
16368
  };
16288
16369
  var tasksParams;
16289
16370
  if (agentId) {