algolia-experiences 1.8.13 → 1.8.15

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.
@@ -1,4 +1,4 @@
1
- /*! algolia-experiences 1.8.13 | © Algolia, Inc. and contributors; MIT License | https://github.com/algolia/instantsearch */
1
+ /*! algolia-experiences 1.8.15 | © Algolia, Inc. and contributors; MIT License | https://github.com/algolia/instantsearch */
2
2
  (function (factory) {
3
3
  typeof define === 'function' && define.amd ? define(factory) :
4
4
  factory();
@@ -4987,7 +4987,7 @@
4987
4987
  function requireVersion() {
4988
4988
  if (hasRequiredVersion) return version$1;
4989
4989
  hasRequiredVersion = 1;
4990
- version$1 = '3.29.1';
4990
+ version$1 = '3.29.2';
4991
4991
  return version$1;
4992
4992
  }
4993
4993
 
@@ -6886,6 +6886,8 @@
6886
6886
  });
6887
6887
  }
6888
6888
 
6889
+ var version = '4.106.0';
6890
+
6889
6891
  var ANONYMOUS_TOKEN_COOKIE_KEY = '_ALGOLIA';
6890
6892
  function getCookie(name) {
6891
6893
  if ((typeof document === "undefined" ? "undefined" : _type_of(document)) !== 'object' || typeof document.cookie !== 'string') {
@@ -6908,6 +6910,232 @@
6908
6910
  return getCookie(ANONYMOUS_TOKEN_COOKIE_KEY);
6909
6911
  }
6910
6912
 
6913
+ function serializePayload(payload) {
6914
+ return btoa(encodeURIComponent(JSON.stringify(payload)));
6915
+ }
6916
+ function deserializePayload(serialized) {
6917
+ return JSON.parse(decodeURIComponent(atob(serialized)));
6918
+ }
6919
+
6920
+ var USAGE_SESSION_KEY = 'ais.usage.sessionId';
6921
+ // Cache the id for the lifetime of the runtime so repeated calls don't hit
6922
+ // `sessionStorage` again, and so we always return the same id even when
6923
+ // storage is unavailable (SSR, privacy mode) and we fall back to a fresh UUID.
6924
+ var usageSessionId = null;
6925
+ function getUsageSessionId() {
6926
+ if (usageSessionId) {
6927
+ return usageSessionId;
6928
+ }
6929
+ try {
6930
+ var existing = sessionStorage.getItem(USAGE_SESSION_KEY);
6931
+ if (existing) {
6932
+ usageSessionId = existing;
6933
+ return usageSessionId;
6934
+ }
6935
+ usageSessionId = createUUID();
6936
+ sessionStorage.setItem(USAGE_SESSION_KEY, usageSessionId);
6937
+ return usageSessionId;
6938
+ } catch (unused) {
6939
+ // sessionStorage unavailable (SSR, privacy mode, etc.)
6940
+ usageSessionId = createUUID();
6941
+ return usageSessionId;
6942
+ }
6943
+ }
6944
+ /** @deprecated use bindEvent instead */ function readDataAttributes(domElement) {
6945
+ var method = domElement.getAttribute('data-insights-method');
6946
+ var serializedPayload = domElement.getAttribute('data-insights-payload');
6947
+ if (typeof serializedPayload !== 'string') {
6948
+ throw new Error('The insights helper expects `data-insights-payload` to be a base64-encoded JSON string.');
6949
+ }
6950
+ try {
6951
+ var payload = deserializePayload(serializedPayload);
6952
+ return {
6953
+ method: method,
6954
+ payload: payload
6955
+ };
6956
+ } catch (error) {
6957
+ throw new Error('The insights helper was unable to parse `data-insights-payload`.');
6958
+ }
6959
+ }
6960
+ /** @deprecated use bindEvent instead */ function writeDataAttributes(param) {
6961
+ var method = param.method, payload = param.payload;
6962
+ if ((typeof payload === "undefined" ? "undefined" : _type_of(payload)) !== 'object') {
6963
+ throw new Error("The insights helper expects the payload to be an object.");
6964
+ }
6965
+ var serializedPayload;
6966
+ try {
6967
+ serializedPayload = serializePayload(payload);
6968
+ } catch (error) {
6969
+ throw new Error("Could not JSON serialize the payload object.");
6970
+ }
6971
+ return 'data-insights-method="'.concat(method, '" data-insights-payload="').concat(serializedPayload, '"');
6972
+ }
6973
+ /**
6974
+ * @deprecated This function 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/
6975
+ */ function insights(method, payload) {
6976
+ return writeDataAttributes({
6977
+ method: method,
6978
+ payload: payload
6979
+ });
6980
+ }
6981
+
6982
+ var now = typeof performance !== 'undefined' ? function() {
6983
+ return performance.now();
6984
+ } : function() {
6985
+ return Date.now();
6986
+ };
6987
+
6988
+ var indexWidgetTypes = [
6989
+ 'ais.index',
6990
+ 'ais.feedContainer'
6991
+ ];
6992
+
6993
+ function isIndexWidget(widget) {
6994
+ return indexWidgetTypes.includes(widget.$$type);
6995
+ }
6996
+
6997
+ function createInitArgs(instantSearchInstance, parent, uiState) {
6998
+ var helper = parent.getHelper();
6999
+ return {
7000
+ uiState: uiState,
7001
+ helper: helper,
7002
+ parent: parent,
7003
+ instantSearchInstance: instantSearchInstance,
7004
+ state: helper.state,
7005
+ renderState: instantSearchInstance.renderState,
7006
+ templatesConfig: instantSearchInstance.templatesConfig,
7007
+ createURL: parent.createURL,
7008
+ scopedResults: [],
7009
+ searchMetadata: {
7010
+ isSearchStalled: instantSearchInstance.status === 'stalled'
7011
+ },
7012
+ status: instantSearchInstance.status,
7013
+ error: instantSearchInstance.error
7014
+ };
7015
+ }
7016
+ function createRenderArgs(instantSearchInstance, parent, widget) {
7017
+ var results = parent.getResultsForWidget(widget);
7018
+ var helper = parent.getHelper();
7019
+ return {
7020
+ helper: helper,
7021
+ parent: parent,
7022
+ instantSearchInstance: instantSearchInstance,
7023
+ results: results,
7024
+ scopedResults: parent.getScopedResults(),
7025
+ state: results && '_state' in results ? results._state : helper.state,
7026
+ renderState: instantSearchInstance.renderState,
7027
+ templatesConfig: instantSearchInstance.templatesConfig,
7028
+ createURL: parent.createURL,
7029
+ searchMetadata: {
7030
+ isSearchStalled: instantSearchInstance.status === 'stalled'
7031
+ },
7032
+ status: instantSearchInstance.status,
7033
+ error: instantSearchInstance.error
7034
+ };
7035
+ }
7036
+ function storeRenderState(param) {
7037
+ var renderState = param.renderState, instantSearchInstance = param.instantSearchInstance, parent = param.parent;
7038
+ var parentIndexName = parent ? parent.getIndexId() : instantSearchInstance.mainIndex.getIndexId();
7039
+ instantSearchInstance.renderState = _object_spread_props(_object_spread({}, instantSearchInstance.renderState), _define_property({}, parentIndexName, _object_spread({}, instantSearchInstance.renderState[parentIndexName], renderState)));
7040
+ }
7041
+
7042
+ function serializeParamValue(value) {
7043
+ if (value === undefined || value === null) {
7044
+ return null;
7045
+ }
7046
+ var t = typeof value === "undefined" ? "undefined" : _type_of(value);
7047
+ if (t === 'string' || t === 'number' || t === 'boolean') {
7048
+ return {
7049
+ value: String(value),
7050
+ type: t
7051
+ };
7052
+ }
7053
+ if (Array.isArray(value) || t === 'object') {
7054
+ var type = Array.isArray(value) ? 'array' : 'object';
7055
+ try {
7056
+ return {
7057
+ value: JSON.stringify(value),
7058
+ type: type
7059
+ };
7060
+ } catch (unused) {
7061
+ return {
7062
+ type: type
7063
+ };
7064
+ }
7065
+ }
7066
+ if (t === 'function') {
7067
+ return {
7068
+ value: value.name,
7069
+ type: 'function'
7070
+ };
7071
+ }
7072
+ // symbols, DOM elements: name only
7073
+ return null;
7074
+ }
7075
+ /**
7076
+ * Turns a `widgetParams`-style record into the serialized `WidgetTreeParam[]`
7077
+ * shape used throughout the usage events. Shared between the widget tree and
7078
+ * the root `ais.instantSearch` node so every node reports params identically.
7079
+ */ function serializeWidgetParams(widgetParams) {
7080
+ var params = [];
7081
+ Object.keys(widgetParams).forEach(function(key) {
7082
+ var raw = widgetParams[key];
7083
+ if (raw === undefined) {
7084
+ return;
7085
+ }
7086
+ var serialized = serializeParamValue(raw);
7087
+ if (serialized) {
7088
+ params.push(_object_spread({
7089
+ name: key
7090
+ }, serialized));
7091
+ } else {
7092
+ params.push({
7093
+ name: key
7094
+ });
7095
+ }
7096
+ });
7097
+ return params;
7098
+ }
7099
+ function buildWidgetTree(widgets, instantSearchInstance) {
7100
+ var parent = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : instantSearchInstance.mainIndex;
7101
+ var initOptions = createInitArgs(instantSearchInstance, parent, instantSearchInstance._initialUiState);
7102
+ return widgets.map(function(widget) {
7103
+ var widgetParams = {};
7104
+ if (widget.getWidgetRenderState) {
7105
+ var renderState = widget.getWidgetRenderState(initOptions);
7106
+ if (renderState && renderState.widgetParams) {
7107
+ widgetParams = renderState.widgetParams;
7108
+ }
7109
+ }
7110
+ var params = serializeWidgetParams(widgetParams);
7111
+ var children = isIndexWidget(widget) ? buildWidgetTree(widget.getWidgets(), instantSearchInstance, widget) : [];
7112
+ return {
7113
+ type: widget.$$widgetType || widget.$$type || 'unknown',
7114
+ params: params,
7115
+ children: children
7116
+ };
7117
+ });
7118
+ }
7119
+
7120
+ /**
7121
+ * Creates a new object with the same keys as the original object, but without the excluded keys.
7122
+ * @param source original object
7123
+ * @param excluded keys to remove from the original object
7124
+ * @returns the new object
7125
+ */ function omit(source, excluded) {
7126
+ if (source === null || source === undefined) {
7127
+ return source;
7128
+ }
7129
+ return Object.keys(source).reduce(function(target, key) {
7130
+ if (excluded.indexOf(key) >= 0) {
7131
+ return target;
7132
+ }
7133
+ var validKey = key;
7134
+ target[validKey] = source[validKey];
7135
+ return target;
7136
+ }, {});
7137
+ }
7138
+
6911
7139
  // eslint-disable-next-line no-restricted-globals
6912
7140
  /**
6913
7141
  * Runs code on browser environments safely.
@@ -6981,8 +7209,20 @@
6981
7209
  }
6982
7210
  }
6983
7211
 
7212
+ function getAlgoliaAgent(client) {
7213
+ var clientTyped = client;
7214
+ return clientTyped.transporter && clientTyped.transporter.userAgent ? clientTyped.transporter.userAgent.value : clientTyped._ua;
7215
+ }
7216
+
6984
7217
  var ALGOLIA_INSIGHTS_VERSION = '2.17.2';
6985
7218
  var ALGOLIA_INSIGHTS_SRC = "https://cdn.jsdelivr.net/npm/search-insights@".concat(ALGOLIA_INSIGHTS_VERSION, "/dist/search-insights.min.js");
7219
+ // InstantSearch options that must never be sent in usage events because
7220
+ // they carry credentials or end-user data. Everything else is reported as-is.
7221
+ var SENSITIVE_OPTIONS = [
7222
+ 'searchClient',
7223
+ 'insightsClient',
7224
+ 'initialUiState'
7225
+ ];
6986
7226
  function createInsightsMiddleware() {
6987
7227
  var props = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
6988
7228
  var _insightsClient = props.insightsClient, insightsInitParams = props.insightsInitParams, onEvent = props.onEvent, _props_$$internal = props.$$internal, $$internal = _props_$$internal === void 0 ? false : _props_$$internal, _props_$$automatic = props.$$automatic, $$automatic = _props_$$automatic === void 0 ? false : _props_$$automatic;
@@ -7072,6 +7312,7 @@
7072
7312
  }
7073
7313
  var initialParameters;
7074
7314
  var helper;
7315
+ var removeStartEventListener = null;
7075
7316
  return {
7076
7317
  $$type: 'ais.insights',
7077
7318
  $$internal: $$internal,
@@ -7246,8 +7487,65 @@
7246
7487
  insightsClientWithLocalCredentials(event.insightsMethod, event.payload);
7247
7488
  } else ;
7248
7489
  };
7490
+ // usage tracking (browser-only)
7491
+ safelyRunOnBrowser(function() {
7492
+ var usageSessionId = getUsageSessionId();
7493
+ function sendUsageEvent(event) {
7494
+ var _helper_state;
7495
+ var userToken = (_helper_state = helper.state) === null || _helper_state === void 0 ? void 0 : _helper_state.userToken;
7496
+ insightsClientWithLocalCredentials('sendEvents', [
7497
+ _object_spread({
7498
+ eventType: 'instantsearch',
7499
+ timestamp: Date.now(),
7500
+ sessionID: usageSessionId,
7501
+ userToken: userToken ? String(userToken) : undefined
7502
+ }, event)
7503
+ ]);
7504
+ }
7505
+ // Send the start event on the first `render`, by which point every
7506
+ // flavor has registered its widgets. `bootstrapMs` then measures the
7507
+ // time between the constructor running and that point, so for flavors
7508
+ // that register widgets right at start (e.g. React) it captures the
7509
+ // cost of adding them.
7510
+ var sendStartEvent = function sendStartEvent() {
7511
+ try {
7512
+ var bootstrapMs = Math.round(now() - instantSearchInstance._createdAt);
7513
+ sendUsageEvent({
7514
+ eventName: '__start__',
7515
+ algoliaAgent: getAlgoliaAgent(instantSearchInstance.client),
7516
+ version: version,
7517
+ applicationId: appId,
7518
+ performance: {
7519
+ bootstrapMs: bootstrapMs
7520
+ },
7521
+ widgets: [
7522
+ {
7523
+ type: 'ais.instantSearch',
7524
+ // The options the instance was created with, serialized the
7525
+ // same way every widget's params are. Derived dynamically from
7526
+ // `_initialOptions` so new options are reported automatically,
7527
+ // minus the keys that carry credentials or user data. Functions
7528
+ // (`onStateChange`, `searchFunction`) report their `fn.name`
7529
+ // when present, tagged `type: 'function'`.
7530
+ params: instantSearchInstance._initialOptions ? serializeWidgetParams(omit(instantSearchInstance._initialOptions, _to_consumable_array(SENSITIVE_OPTIONS))) : [],
7531
+ children: buildWidgetTree(instantSearchInstance.mainIndex.getWidgets(), instantSearchInstance)
7532
+ }
7533
+ ]
7534
+ });
7535
+ } catch (unused) {
7536
+ // usage tracking must never crash the host app
7537
+ }
7538
+ };
7539
+ instantSearchInstance.once('render', sendStartEvent);
7540
+ removeStartEventListener = function removeStartEventListener() {
7541
+ return instantSearchInstance.removeListener('render', sendStartEvent);
7542
+ };
7543
+ });
7249
7544
  },
7250
7545
  unsubscribe: function unsubscribe() {
7546
+ if (removeStartEventListener) {
7547
+ removeStartEventListener();
7548
+ }
7251
7549
  insightsClient('onUserTokenChange', undefined);
7252
7550
  instantSearchInstance.sendEventToInsights = noop;
7253
7551
  if (helper && initialParameters) {
@@ -7295,67 +7593,9 @@
7295
7593
  return typeof userToken === 'number' ? userToken.toString() : userToken;
7296
7594
  }
7297
7595
 
7298
- var indexWidgetTypes = [
7299
- 'ais.index',
7300
- 'ais.feedContainer'
7301
- ];
7302
-
7303
- function isIndexWidget(widget) {
7304
- return indexWidgetTypes.includes(widget.$$type);
7305
- }
7306
-
7307
- function getAlgoliaAgent(client) {
7308
- var clientTyped = client;
7309
- return clientTyped.transporter && clientTyped.transporter.userAgent ? clientTyped.transporter.userAgent.value : clientTyped._ua;
7310
- }
7311
-
7312
- function createInitArgs(instantSearchInstance, parent, uiState) {
7313
- var helper = parent.getHelper();
7314
- return {
7315
- uiState: uiState,
7316
- helper: helper,
7317
- parent: parent,
7318
- instantSearchInstance: instantSearchInstance,
7319
- state: helper.state,
7320
- renderState: instantSearchInstance.renderState,
7321
- templatesConfig: instantSearchInstance.templatesConfig,
7322
- createURL: parent.createURL,
7323
- scopedResults: [],
7324
- searchMetadata: {
7325
- isSearchStalled: instantSearchInstance.status === 'stalled'
7326
- },
7327
- status: instantSearchInstance.status,
7328
- error: instantSearchInstance.error
7329
- };
7330
- }
7331
- function createRenderArgs(instantSearchInstance, parent, widget) {
7332
- var results = parent.getResultsForWidget(widget);
7333
- var helper = parent.getHelper();
7334
- return {
7335
- helper: helper,
7336
- parent: parent,
7337
- instantSearchInstance: instantSearchInstance,
7338
- results: results,
7339
- scopedResults: parent.getScopedResults(),
7340
- state: results && '_state' in results ? results._state : helper.state,
7341
- renderState: instantSearchInstance.renderState,
7342
- templatesConfig: instantSearchInstance.templatesConfig,
7343
- createURL: parent.createURL,
7344
- searchMetadata: {
7345
- isSearchStalled: instantSearchInstance.status === 'stalled'
7346
- },
7347
- status: instantSearchInstance.status,
7348
- error: instantSearchInstance.error
7349
- };
7350
- }
7351
- function storeRenderState(param) {
7352
- var renderState = param.renderState, instantSearchInstance = param.instantSearchInstance, parent = param.parent;
7353
- var parentIndexName = parent ? parent.getIndexId() : instantSearchInstance.mainIndex.getIndexId();
7354
- instantSearchInstance.renderState = _object_spread_props(_object_spread({}, instantSearchInstance.renderState), _define_property({}, parentIndexName, _object_spread({}, instantSearchInstance.renderState[parentIndexName], renderState)));
7355
- }
7356
-
7357
7596
  function extractWidgetPayload(widgets, instantSearchInstance, payload) {
7358
- var initOptions = createInitArgs(instantSearchInstance, instantSearchInstance.mainIndex, instantSearchInstance._initialUiState);
7597
+ var parent = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : instantSearchInstance.mainIndex;
7598
+ var initOptions = createInitArgs(instantSearchInstance, parent, instantSearchInstance._initialUiState);
7359
7599
  widgets.forEach(function(widget) {
7360
7600
  var widgetParams = {};
7361
7601
  if (widget.getWidgetRenderState) {
@@ -7375,10 +7615,11 @@
7375
7615
  params: params
7376
7616
  });
7377
7617
  if (isIndexWidget(widget)) {
7378
- extractWidgetPayload(widget.getWidgets(), instantSearchInstance, payload);
7618
+ extractWidgetPayload(widget.getWidgets(), instantSearchInstance, payload, widget);
7379
7619
  }
7380
7620
  });
7381
7621
  }
7622
+
7382
7623
  function isMetadataEnabled() {
7383
7624
  return safelyRunOnBrowser(function(param) {
7384
7625
  var window = param.window;
@@ -9876,51 +10117,6 @@
9876
10117
  return reverseHighlightedValue.replace(new RegExp(TAG_REPLACEMENT.highlightPreTag, 'g'), "<".concat(highlightedTagName, ' class="').concat(className, '">')).replace(new RegExp(TAG_REPLACEMENT.highlightPostTag, 'g'), "</".concat(highlightedTagName, ">"));
9877
10118
  }
9878
10119
 
9879
- function serializePayload(payload) {
9880
- return btoa(encodeURIComponent(JSON.stringify(payload)));
9881
- }
9882
- function deserializePayload(serialized) {
9883
- return JSON.parse(decodeURIComponent(atob(serialized)));
9884
- }
9885
-
9886
- /** @deprecated use bindEvent instead */ function readDataAttributes(domElement) {
9887
- var method = domElement.getAttribute('data-insights-method');
9888
- var serializedPayload = domElement.getAttribute('data-insights-payload');
9889
- if (typeof serializedPayload !== 'string') {
9890
- throw new Error('The insights helper expects `data-insights-payload` to be a base64-encoded JSON string.');
9891
- }
9892
- try {
9893
- var payload = deserializePayload(serializedPayload);
9894
- return {
9895
- method: method,
9896
- payload: payload
9897
- };
9898
- } catch (error) {
9899
- throw new Error('The insights helper was unable to parse `data-insights-payload`.');
9900
- }
9901
- }
9902
- /** @deprecated use bindEvent instead */ function writeDataAttributes(param) {
9903
- var method = param.method, payload = param.payload;
9904
- if ((typeof payload === "undefined" ? "undefined" : _type_of(payload)) !== 'object') {
9905
- throw new Error("The insights helper expects the payload to be an object.");
9906
- }
9907
- var serializedPayload;
9908
- try {
9909
- serializedPayload = serializePayload(payload);
9910
- } catch (error) {
9911
- throw new Error("Could not JSON serialize the payload object.");
9912
- }
9913
- return 'data-insights-method="'.concat(method, '" data-insights-payload="').concat(serializedPayload, '"');
9914
- }
9915
- /**
9916
- * @deprecated This function 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/
9917
- */ function insights(method, payload) {
9918
- return writeDataAttributes({
9919
- method: method,
9920
- payload: payload
9921
- });
9922
- }
9923
-
9924
10120
  function hoganHelpers(param) {
9925
10121
  var numberLocale = param.numberLocale;
9926
10122
  return {
@@ -9982,8 +10178,6 @@
9982
10178
  };
9983
10179
  }
9984
10180
 
9985
- var version = '4.104.0';
9986
-
9987
10181
  function getServerResults(entry) {
9988
10182
  var _entry_compositionFeedsResults;
9989
10183
  return ((_entry_compositionFeedsResults = entry.compositionFeedsResults) === null || _entry_compositionFeedsResults === void 0 ? void 0 : _entry_compositionFeedsResults.length) ? entry.compositionFeedsResults : entry.results || [];
@@ -10142,7 +10336,14 @@
10142
10336
  function InstantSearch(options) {
10143
10337
  _class_call_check(this, InstantSearch);
10144
10338
  var _this;
10145
- _this = _call_super(this, InstantSearch), _define_property(_this, "client", void 0), _define_property(_this, "indexName", void 0), _define_property(_this, "compositionID", void 0), _define_property(_this, "insightsClient", void 0), _define_property(_this, "onStateChange", null), _define_property(_this, "future", void 0), _define_property(_this, "helper", void 0), _define_property(_this, "mainHelper", void 0), _define_property(_this, "mainIndex", void 0), _define_property(_this, "started", void 0), _define_property(_this, "templatesConfig", void 0), _define_property(_this, "renderState", {}), _define_property(_this, "_stalledSearchDelay", void 0), _define_property(_this, "_searchStalledTimer", void 0), _define_property(_this, "_initialUiState", void 0), _define_property(_this, "_initialResults", void 0), _define_property(_this, "_manuallyResetScheduleSearch", false), _define_property(_this, "_resetScheduleSearch", void 0), _define_property(_this, "_createURL", void 0), _define_property(_this, "_searchFunction", void 0), _define_property(_this, "_mainHelperSearch", void 0), _define_property(_this, "_hasSearchWidget", false), _define_property(_this, "_hasRecommendWidget", false), _define_property(_this, "_insights", void 0), _define_property(_this, "middleware", []), _define_property(_this, "sendEventToInsights", void 0), /**
10339
+ _this = _call_super(this, InstantSearch), _define_property(_this, "client", void 0), _define_property(_this, "indexName", void 0), _define_property(_this, "compositionID", void 0), _define_property(_this, "insightsClient", void 0), _define_property(_this, "onStateChange", null), _define_property(_this, "future", void 0), _define_property(_this, "helper", void 0), _define_property(_this, "mainHelper", void 0), _define_property(_this, "mainIndex", void 0), _define_property(_this, "started", void 0), _define_property(_this, "templatesConfig", void 0), _define_property(_this, "renderState", {}), _define_property(_this, "_stalledSearchDelay", void 0), _define_property(_this, "_searchStalledTimer", void 0), _define_property(_this, "_initialUiState", void 0), _define_property(_this, "_initialResults", void 0), _define_property(_this, "_manuallyResetScheduleSearch", false), _define_property(_this, "_resetScheduleSearch", void 0), _define_property(_this, "_createURL", void 0), _define_property(_this, "_searchFunction", void 0), _define_property(_this, "_mainHelperSearch", void 0), _define_property(_this, "_hasSearchWidget", false), _define_property(_this, "_hasRecommendWidget", false), _define_property(_this, "_insights", void 0), /**
10340
+ * The options the instance was created with, kept verbatim so consumers
10341
+ * (e.g. usage events) can introspect the configuration without the class
10342
+ * having to enumerate every option by hand. Typed without the class generics
10343
+ * on purpose: referencing `TUiState`/`TRouteState` here (they sit in
10344
+ * contravariant positions inside `InstantSearchOptions`) would break the
10345
+ * assignability of `InstantSearch<SpecificUiState>` to `InstantSearch`.
10346
+ */ _define_property(_this, "_initialOptions", void 0), _define_property(_this, "middleware", []), _define_property(_this, "sendEventToInsights", void 0), _define_property(_this, "_createdAt", now()), /**
10146
10347
  * The status of the search. Can be "idle", "loading", "stalled", or "error".
10147
10348
  */ _define_property(_this, "status", 'idle'), /**
10148
10349
  * The last returned error from the Search API.
@@ -10190,6 +10391,7 @@
10190
10391
  if (insightsClient && typeof insightsClient !== 'function') {
10191
10392
  throw new Error(withUsage$J('The `insightsClient` option should be a function.'));
10192
10393
  }
10394
+ _this._initialOptions = options;
10193
10395
  _this.client = searchClient;
10194
10396
  _this.future = future;
10195
10397
  _this.insightsClient = insightsClient;
@@ -10562,6 +10764,9 @@
10562
10764
  var instance = param.instance;
10563
10765
  instance.unsubscribe();
10564
10766
  });
10767
+ // Cleared after unsubscribe so in-flight readers (e.g. the insights
10768
+ // start-event listener) have detached before the reference goes away.
10769
+ this._initialOptions = null;
10565
10770
  }
10566
10771
  },
10567
10772
  {
@@ -11143,25 +11348,6 @@
11143
11348
  return widget.$$type === 'ais.dynamicWidgets' || widget.$$type === 'ais.feeds';
11144
11349
  }
11145
11350
 
11146
- /**
11147
- * Creates a new object with the same keys as the original object, but without the excluded keys.
11148
- * @param source original object
11149
- * @param excluded keys to remove from the original object
11150
- * @returns the new object
11151
- */ function omit(source, excluded) {
11152
- if (source === null || source === undefined) {
11153
- return source;
11154
- }
11155
- return Object.keys(source).reduce(function(target, key) {
11156
- if (excluded.indexOf(key) >= 0) {
11157
- return target;
11158
- }
11159
- var validKey = key;
11160
- target[validKey] = source[validKey];
11161
- return target;
11162
- }, {});
11163
- }
11164
-
11165
11351
  function range(param) {
11166
11352
  var _param_start = param.start, start = _param_start === void 0 ? 0 : _param_start, end = param.end, _param_step = param.step, step = _param_step === void 0 ? 1 : _param_step;
11167
11353
  // We can't divide by 0 so we re-assign the step to 1 if it happens.
@@ -13963,6 +14149,8 @@
13963
14149
  isSearchStalled: false,
13964
14150
  disabled: false,
13965
14151
  ariaLabel: 'Search',
14152
+ submitTitle: 'Submit the search query',
14153
+ resetTitle: 'Clear the search query',
13966
14154
  onChange: noop,
13967
14155
  onSubmit: noop,
13968
14156
  onReset: noop,
@@ -14102,7 +14290,8 @@
14102
14290
  rootProps: {
14103
14291
  className: cssClasses.submit,
14104
14292
  type: 'submit',
14105
- title: 'Submit the search query',
14293
+ title: this.props.submitTitle,
14294
+ 'aria-label': this.props.submitTitle,
14106
14295
  hidden: !showSubmit
14107
14296
  },
14108
14297
  templates: templates,
@@ -14115,7 +14304,8 @@
14115
14304
  rootProps: {
14116
14305
  className: cssClasses.reset,
14117
14306
  type: 'reset',
14118
- title: 'Clear the search query',
14307
+ title: this.props.resetTitle,
14308
+ 'aria-label': this.props.resetTitle,
14119
14309
  hidden: !(showReset && this.state.query.trim() && !isSearchStalled)
14120
14310
  },
14121
14311
  templates: templates,
@@ -14340,7 +14530,9 @@
14340
14530
  rootProps: {
14341
14531
  className: showMoreButtonClassName,
14342
14532
  disabled: !this.props.canToggleShowMore,
14343
- onClick: this.props.toggleShowMore
14533
+ onClick: this.props.toggleShowMore,
14534
+ 'aria-expanded': Boolean(this.props.isShowingMore),
14535
+ 'aria-label': this.props.showMoreButtonLabel
14344
14536
  },
14345
14537
  data: {
14346
14538
  isShowingMore: this.props.isShowingMore
@@ -16480,6 +16672,7 @@
16480
16672
  rootProps: {
16481
16673
  className: cssClasses.link,
16482
16674
  'aria-label': ariaLabel,
16675
+ 'aria-current': isSelected ? 'page' : undefined,
16483
16676
  href: createURL(pageNumber),
16484
16677
  onClick: createClickHandler(pageNumber)
16485
16678
  },
@@ -19050,7 +19243,7 @@
19050
19243
  var suit$4 = component('RefinementList');
19051
19244
  var searchBoxSuit = component('SearchBox');
19052
19245
  var renderer$6 = function renderer(param) {
19053
- var containerNode = param.containerNode, cssClasses = param.cssClasses, templates = param.templates, searchBoxTemplates = param.searchBoxTemplates, renderState = param.renderState, showMore = param.showMore, searchable = param.searchable, searchablePlaceholder = param.searchablePlaceholder, searchableIsAlwaysActive = param.searchableIsAlwaysActive, searchableSelectOnSubmit = param.searchableSelectOnSubmit;
19246
+ var containerNode = param.containerNode, cssClasses = param.cssClasses, templates = param.templates, searchBoxTemplates = param.searchBoxTemplates, renderState = param.renderState, showMore = param.showMore, showMoreButtonLabel = param.showMoreButtonLabel, searchable = param.searchable, searchablePlaceholder = param.searchablePlaceholder, searchableIsAlwaysActive = param.searchableIsAlwaysActive, searchableSelectOnSubmit = param.searchableSelectOnSubmit;
19054
19247
  return function(param, isFirstRendering) {
19055
19248
  var refine = param.refine, items = param.items, createURL = param.createURL, searchForItems = param.searchForItems, isFromSearch = param.isFromSearch, instantSearchInstance = param.instantSearchInstance, toggleShowMore = param.toggleShowMore, isShowingMore = param.isShowingMore, hasExhaustiveItems = param.hasExhaustiveItems, canToggleShowMore = param.canToggleShowMore;
19056
19249
  if (isFirstRendering) {
@@ -19078,6 +19271,7 @@
19078
19271
  searchIsAlwaysActive: searchableIsAlwaysActive,
19079
19272
  isFromSearch: isFromSearch,
19080
19273
  showMore: showMore && !isFromSearch && items.length > 0,
19274
+ showMoreButtonLabel: showMoreButtonLabel,
19081
19275
  toggleShowMore: toggleShowMore,
19082
19276
  isShowingMore: isShowingMore,
19083
19277
  hasExhaustiveItems: hasExhaustiveItems,
@@ -19105,7 +19299,7 @@
19105
19299
  *
19106
19300
  * If you also want to use search for facet values on this attribute, you need to make it searchable using the [dashboard](https://www.algolia.com/explorer/display/) or using the [API](https://www.algolia.com/doc/guides/searching/faceting/#search-for-facet-values).
19107
19301
  */ var refinementList = function refinementList(widgetParams) {
19108
- var _ref = widgetParams || {}, container = _ref.container, attribute = _ref.attribute, operator = _ref.operator, sortBy = _ref.sortBy, limit = _ref.limit, showMore = _ref.showMore, showMoreLimit = _ref.showMoreLimit, _ref_searchable = _ref.searchable, searchable = _ref_searchable === void 0 ? false : _ref_searchable, _ref_searchablePlaceholder = _ref.searchablePlaceholder, searchablePlaceholder = _ref_searchablePlaceholder === void 0 ? 'Search...' : _ref_searchablePlaceholder, _ref_searchableEscapeFacetValues = _ref.searchableEscapeFacetValues, searchableEscapeFacetValues = _ref_searchableEscapeFacetValues === void 0 ? true : _ref_searchableEscapeFacetValues, _ref_searchableIsAlwaysActive = _ref.searchableIsAlwaysActive, searchableIsAlwaysActive = _ref_searchableIsAlwaysActive === void 0 ? true : _ref_searchableIsAlwaysActive, _ref_searchableSelectOnSubmit = _ref.searchableSelectOnSubmit, searchableSelectOnSubmit = _ref_searchableSelectOnSubmit === void 0 ? true : _ref_searchableSelectOnSubmit, tmp = _ref.cssClasses, userCssClasses = tmp === void 0 ? {} : tmp, _ref_templates = _ref.templates, templates = _ref_templates === void 0 ? {} : _ref_templates, transformItems = _ref.transformItems;
19302
+ var _ref = widgetParams || {}, container = _ref.container, attribute = _ref.attribute, operator = _ref.operator, sortBy = _ref.sortBy, limit = _ref.limit, showMore = _ref.showMore, showMoreLimit = _ref.showMoreLimit, showMoreButtonLabel = _ref.showMoreButtonLabel, _ref_searchable = _ref.searchable, searchable = _ref_searchable === void 0 ? false : _ref_searchable, _ref_searchablePlaceholder = _ref.searchablePlaceholder, searchablePlaceholder = _ref_searchablePlaceholder === void 0 ? 'Search...' : _ref_searchablePlaceholder, _ref_searchableEscapeFacetValues = _ref.searchableEscapeFacetValues, searchableEscapeFacetValues = _ref_searchableEscapeFacetValues === void 0 ? true : _ref_searchableEscapeFacetValues, _ref_searchableIsAlwaysActive = _ref.searchableIsAlwaysActive, searchableIsAlwaysActive = _ref_searchableIsAlwaysActive === void 0 ? true : _ref_searchableIsAlwaysActive, _ref_searchableSelectOnSubmit = _ref.searchableSelectOnSubmit, searchableSelectOnSubmit = _ref_searchableSelectOnSubmit === void 0 ? true : _ref_searchableSelectOnSubmit, tmp = _ref.cssClasses, userCssClasses = tmp === void 0 ? {} : tmp, _ref_templates = _ref.templates, templates = _ref_templates === void 0 ? {} : _ref_templates, transformItems = _ref.transformItems;
19109
19303
  if (!container) {
19110
19304
  throw new Error(withUsage$d('The `container` option is required.'));
19111
19305
  }
@@ -19193,7 +19387,8 @@
19193
19387
  searchablePlaceholder: searchablePlaceholder,
19194
19388
  searchableIsAlwaysActive: searchableIsAlwaysActive,
19195
19389
  searchableSelectOnSubmit: searchableSelectOnSubmit,
19196
- showMore: showMore
19390
+ showMore: showMore,
19391
+ showMoreButtonLabel: showMoreButtonLabel
19197
19392
  });
19198
19393
  var makeWidget = connectRefinementList(specializedRenderer, function() {
19199
19394
  return P(null, containerNode);
@@ -19218,7 +19413,7 @@
19218
19413
  var suit$3 = component('SearchBox');
19219
19414
  var aiModeSuit = component('AiModeButton');
19220
19415
  var renderer$5 = function renderer(param) {
19221
- var containerNode = param.containerNode, cssClasses = param.cssClasses, placeholder = param.placeholder, templates = param.templates, autofocus = param.autofocus, searchAsYouType = param.searchAsYouType, ignoreCompositionEvents = param.ignoreCompositionEvents, showReset = param.showReset, showSubmit = param.showSubmit, showLoadingIndicator = param.showLoadingIndicator, aiMode = param.aiMode;
19416
+ var containerNode = param.containerNode, cssClasses = param.cssClasses, placeholder = param.placeholder, templates = param.templates, autofocus = param.autofocus, searchAsYouType = param.searchAsYouType, ignoreCompositionEvents = param.ignoreCompositionEvents, showReset = param.showReset, showSubmit = param.showSubmit, showLoadingIndicator = param.showLoadingIndicator, submitTitle = param.submitTitle, resetTitle = param.resetTitle, aiMode = param.aiMode;
19222
19417
  return function(param) {
19223
19418
  var refine = param.refine, query = param.query, isSearchStalled = param.isSearchStalled, instantSearchInstance = param.instantSearchInstance;
19224
19419
  var getChatRenderState = function getChatRenderState() {
@@ -19246,6 +19441,8 @@
19246
19441
  showSubmit: showSubmit,
19247
19442
  showReset: showReset,
19248
19443
  showLoadingIndicator: showLoadingIndicator,
19444
+ submitTitle: submitTitle,
19445
+ resetTitle: resetTitle,
19249
19446
  isSearchStalled: isSearchStalled,
19250
19447
  cssClasses: cssClasses,
19251
19448
  onAiModeClick: onAiModeClick,
@@ -19254,7 +19451,7 @@
19254
19451
  };
19255
19452
  };
19256
19453
  var searchBox = function searchBox(widgetParams) {
19257
- var _ref = widgetParams || {}, container = _ref.container, _ref_placeholder = _ref.placeholder, placeholder = _ref_placeholder === void 0 ? '' : _ref_placeholder, tmp = _ref.cssClasses, userCssClasses = tmp === void 0 ? {} : tmp, _ref_autofocus = _ref.autofocus, autofocus = _ref_autofocus === void 0 ? false : _ref_autofocus, _ref_searchAsYouType = _ref.searchAsYouType, searchAsYouType = _ref_searchAsYouType === void 0 ? true : _ref_searchAsYouType, _ref_ignoreCompositionEvents = _ref.ignoreCompositionEvents, ignoreCompositionEvents = _ref_ignoreCompositionEvents === void 0 ? false : _ref_ignoreCompositionEvents, _ref_showReset = _ref.showReset, showReset = _ref_showReset === void 0 ? true : _ref_showReset, _ref_showSubmit = _ref.showSubmit, showSubmit = _ref_showSubmit === void 0 ? true : _ref_showSubmit, _ref_showLoadingIndicator = _ref.showLoadingIndicator, showLoadingIndicator = _ref_showLoadingIndicator === void 0 ? true : _ref_showLoadingIndicator, queryHook = _ref.queryHook, tmp1 = _ref.templates, userTemplates = tmp1 === void 0 ? {} : tmp1, aiMode = _ref.aiMode;
19454
+ var _ref = widgetParams || {}, container = _ref.container, _ref_placeholder = _ref.placeholder, placeholder = _ref_placeholder === void 0 ? '' : _ref_placeholder, tmp = _ref.cssClasses, userCssClasses = tmp === void 0 ? {} : tmp, _ref_autofocus = _ref.autofocus, autofocus = _ref_autofocus === void 0 ? false : _ref_autofocus, _ref_searchAsYouType = _ref.searchAsYouType, searchAsYouType = _ref_searchAsYouType === void 0 ? true : _ref_searchAsYouType, _ref_ignoreCompositionEvents = _ref.ignoreCompositionEvents, ignoreCompositionEvents = _ref_ignoreCompositionEvents === void 0 ? false : _ref_ignoreCompositionEvents, _ref_showReset = _ref.showReset, showReset = _ref_showReset === void 0 ? true : _ref_showReset, _ref_showSubmit = _ref.showSubmit, showSubmit = _ref_showSubmit === void 0 ? true : _ref_showSubmit, _ref_showLoadingIndicator = _ref.showLoadingIndicator, showLoadingIndicator = _ref_showLoadingIndicator === void 0 ? true : _ref_showLoadingIndicator, _ref_submitTitle = _ref.submitTitle, submitTitle = _ref_submitTitle === void 0 ? 'Submit the search query' : _ref_submitTitle, _ref_resetTitle = _ref.resetTitle, resetTitle = _ref_resetTitle === void 0 ? 'Clear the search query' : _ref_resetTitle, queryHook = _ref.queryHook, tmp1 = _ref.templates, userTemplates = tmp1 === void 0 ? {} : tmp1, aiMode = _ref.aiMode;
19258
19455
  if (!container) {
19259
19456
  throw new Error(withUsage$c('The `container` option is required.'));
19260
19457
  }
@@ -19305,6 +19502,8 @@
19305
19502
  showReset: showReset,
19306
19503
  showSubmit: showSubmit,
19307
19504
  showLoadingIndicator: showLoadingIndicator,
19505
+ submitTitle: submitTitle,
19506
+ resetTitle: resetTitle,
19308
19507
  aiMode: aiMode
19309
19508
  });
19310
19509
  var widgetFactory = connectSearchBox(specializedRenderer, function() {
@@ -19538,13 +19737,70 @@
19538
19737
  });
19539
19738
  };
19540
19739
 
19740
+ // Delay before announcing an update, so that rapid changes (e.g. typing in the
19741
+ // search box) settle into a single announcement instead of piling up. Mirrors
19742
+ // the debounce used by GOV.UK's accessible-autocomplete.
19743
+ var ANNOUNCEMENT_DELAY = 1400;
19744
+ var visuallyHiddenStyle = {
19745
+ position: 'absolute',
19746
+ width: '1px',
19747
+ height: '1px',
19748
+ padding: 0,
19749
+ margin: '-1px',
19750
+ overflow: 'hidden',
19751
+ clip: 'rect(0, 0, 0, 0)',
19752
+ whiteSpace: 'nowrap',
19753
+ border: 0
19754
+ };
19755
+ // Result count without the volatile details (such as the processing time) that
19756
+ // are part of the visible text, so that only the meaningful count is announced.
19757
+ function getAnnouncement(nbHits, nbSortedHits, areHitsSorted) {
19758
+ if (areHitsSorted) {
19759
+ var suffix = "sorted out of ".concat(formatNumber(nbHits));
19760
+ if (nbSortedHits === 0) {
19761
+ return "No relevant results ".concat(suffix);
19762
+ }
19763
+ if (nbSortedHits === 1) {
19764
+ return "1 relevant result ".concat(suffix);
19765
+ }
19766
+ return "".concat(formatNumber(nbSortedHits || 0), " relevant results ").concat(suffix);
19767
+ }
19768
+ if (nbHits === 0) {
19769
+ return 'No results';
19770
+ }
19771
+ if (nbHits === 1) {
19772
+ return '1 result';
19773
+ }
19774
+ return "".concat(formatNumber(nbHits), " results");
19775
+ }
19541
19776
  var Stats = function Stats(_0) {
19542
- var nbHits = _0.nbHits, nbSortedHits = _0.nbSortedHits, cssClasses = _0.cssClasses, templateProps = _0.templateProps, rest = _object_without_properties(_0, [
19777
+ var nbHits = _0.nbHits, nbSortedHits = _0.nbSortedHits, areHitsSorted = _0.areHitsSorted, cssClasses = _0.cssClasses, templateProps = _0.templateProps, rest = _object_without_properties(_0, [
19543
19778
  "nbHits",
19544
19779
  "nbSortedHits",
19780
+ "areHitsSorted",
19545
19781
  "cssClasses",
19546
19782
  "templateProps"
19547
19783
  ]);
19784
+ var nextAnnouncement = getAnnouncement(nbHits, nbSortedHits, areHitsSorted);
19785
+ var _useState = _sliced_to_array(y(''), 2), announcement = _useState[0], setAnnouncement = _useState[1];
19786
+ var timerRef = A();
19787
+ var isInitialRef = A(true);
19788
+ s(function() {
19789
+ // Don't announce the initial results, only subsequent changes.
19790
+ if (isInitialRef.current) {
19791
+ isInitialRef.current = false;
19792
+ return undefined;
19793
+ }
19794
+ clearTimeout(timerRef.current);
19795
+ timerRef.current = setTimeout(function() {
19796
+ setAnnouncement(nextAnnouncement);
19797
+ }, ANNOUNCEMENT_DELAY);
19798
+ return function() {
19799
+ return clearTimeout(timerRef.current);
19800
+ };
19801
+ }, [
19802
+ nextAnnouncement
19803
+ ]);
19548
19804
  return /*#__PURE__*/ h$1("div", {
19549
19805
  className: cx(cssClasses.root)
19550
19806
  }, /*#__PURE__*/ h$1(Template, _object_spread_props(_object_spread({}, templateProps), {
@@ -19562,9 +19818,16 @@
19562
19818
  hasOneResult: nbHits === 1,
19563
19819
  nbHits: nbHits,
19564
19820
  nbSortedHits: nbSortedHits,
19821
+ areHitsSorted: areHitsSorted,
19565
19822
  cssClasses: cssClasses
19566
19823
  }, rest)
19567
- })));
19824
+ })), /*#__PURE__*/ h$1("span", {
19825
+ className: "ais-Stats-announcement",
19826
+ role: "status",
19827
+ "aria-live": "polite",
19828
+ "aria-atomic": "true",
19829
+ style: visuallyHiddenStyle
19830
+ }, announcement));
19568
19831
  };
19569
19832
 
19570
19833
  var withUsage$9 = createDocumentationMessageGenerator({