@algolia/autocomplete-core 1.3.0 → 1.5.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.
- package/dist/esm/createAutocomplete.d.ts +8 -2
- package/dist/esm/createAutocomplete.js +9 -1
- package/dist/esm/createStore.js +3 -2
- package/dist/esm/getAutocompleteSetters.js +1 -1
- package/dist/esm/getDefaultProps.js +2 -2
- package/dist/esm/getPropGetters.js +41 -13
- package/dist/esm/index.d.ts +0 -1
- package/dist/esm/index.js +1 -2
- package/dist/esm/metadata.d.ts +33 -0
- package/dist/esm/metadata.js +44 -0
- package/dist/esm/onInput.d.ts +3 -0
- package/dist/esm/onInput.js +69 -40
- package/dist/esm/onKeyDown.js +12 -3
- package/dist/esm/reshape.js +1 -1
- package/dist/esm/resolve.js +2 -2
- package/dist/esm/stateReducer.js +1 -1
- package/dist/esm/types/AutocompleteApi.js +1 -0
- package/dist/esm/types/AutocompleteCollection.js +1 -0
- package/dist/esm/types/AutocompleteContext.js +1 -0
- package/dist/esm/types/AutocompleteEnvironment.d.ts +1 -0
- package/dist/esm/types/AutocompleteEnvironment.js +1 -0
- package/dist/esm/types/AutocompleteNavigator.js +1 -0
- package/dist/esm/types/AutocompleteOptions.js +1 -0
- package/dist/esm/types/AutocompletePlugin.d.ts +10 -0
- package/dist/esm/types/AutocompletePlugin.js +1 -0
- package/dist/esm/types/AutocompletePropGetters.js +1 -0
- package/dist/esm/types/AutocompleteReshape.js +1 -0
- package/dist/esm/types/AutocompleteSetters.js +1 -0
- package/dist/esm/types/AutocompleteSource.js +1 -0
- package/dist/esm/types/AutocompleteState.js +1 -0
- package/dist/esm/types/AutocompleteStore.d.ts +1 -0
- package/dist/esm/types/AutocompleteStore.js +1 -0
- package/dist/esm/types/AutocompleteSubscribers.js +1 -0
- package/dist/esm/utils/createConcurrentSafePromise.d.ts +4 -1
- package/dist/esm/utils/createConcurrentSafePromise.js +12 -1
- package/dist/esm/utils/getNormalizedSources.js +2 -3
- package/dist/esm/utils/index.d.ts +0 -1
- package/dist/esm/utils/index.js +1 -2
- package/dist/esm/utils/mapToAlgoliaResponse.js +1 -1
- package/dist/umd/index.development.js +289 -120
- package/dist/umd/index.development.js.map +1 -1
- package/dist/umd/index.production.js +2 -2
- package/dist/umd/index.production.js.map +1 -1
- package/package.json +3 -3
- package/dist/esm/utils/noop.d.ts +0 -1
- package/dist/esm/utils/noop.js +0 -1
- package/dist/esm/version.d.ts +0 -1
- package/dist/esm/version.js +0 -1
|
@@ -1,49 +1,22 @@
|
|
|
1
|
-
/*! @algolia/autocomplete-core 1.
|
|
1
|
+
/*! @algolia/autocomplete-core 1.5.1 | MIT License | © Algolia, Inc. and contributors | https://github.com/algolia/autocomplete */
|
|
2
2
|
(function (global, factory) {
|
|
3
3
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
4
4
|
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
5
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global[
|
|
6
|
-
}(this, (function (exports) { 'use strict';
|
|
7
|
-
|
|
8
|
-
function _typeof(obj) {
|
|
9
|
-
"@babel/helpers - typeof";
|
|
10
|
-
|
|
11
|
-
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
|
|
12
|
-
_typeof = function (obj) {
|
|
13
|
-
return typeof obj;
|
|
14
|
-
};
|
|
15
|
-
} else {
|
|
16
|
-
_typeof = function (obj) {
|
|
17
|
-
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return _typeof(obj);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function _defineProperty(obj, key, value) {
|
|
25
|
-
if (key in obj) {
|
|
26
|
-
Object.defineProperty(obj, key, {
|
|
27
|
-
value: value,
|
|
28
|
-
enumerable: true,
|
|
29
|
-
configurable: true,
|
|
30
|
-
writable: true
|
|
31
|
-
});
|
|
32
|
-
} else {
|
|
33
|
-
obj[key] = value;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return obj;
|
|
37
|
-
}
|
|
5
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["@algolia/autocomplete-core"] = {}));
|
|
6
|
+
})(this, (function (exports) { 'use strict';
|
|
38
7
|
|
|
39
8
|
function ownKeys(object, enumerableOnly) {
|
|
40
9
|
var keys = Object.keys(object);
|
|
41
10
|
|
|
42
11
|
if (Object.getOwnPropertySymbols) {
|
|
43
12
|
var symbols = Object.getOwnPropertySymbols(object);
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
13
|
+
|
|
14
|
+
if (enumerableOnly) {
|
|
15
|
+
symbols = symbols.filter(function (sym) {
|
|
16
|
+
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
47
20
|
keys.push.apply(keys, symbols);
|
|
48
21
|
}
|
|
49
22
|
|
|
@@ -70,6 +43,37 @@
|
|
|
70
43
|
return target;
|
|
71
44
|
}
|
|
72
45
|
|
|
46
|
+
function _typeof$1(obj) {
|
|
47
|
+
"@babel/helpers - typeof";
|
|
48
|
+
|
|
49
|
+
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
|
|
50
|
+
_typeof$1 = function (obj) {
|
|
51
|
+
return typeof obj;
|
|
52
|
+
};
|
|
53
|
+
} else {
|
|
54
|
+
_typeof$1 = function (obj) {
|
|
55
|
+
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return _typeof$1(obj);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function _defineProperty(obj, key, value) {
|
|
63
|
+
if (key in obj) {
|
|
64
|
+
Object.defineProperty(obj, key, {
|
|
65
|
+
value: value,
|
|
66
|
+
enumerable: true,
|
|
67
|
+
configurable: true,
|
|
68
|
+
writable: true
|
|
69
|
+
});
|
|
70
|
+
} else {
|
|
71
|
+
obj[key] = value;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return obj;
|
|
75
|
+
}
|
|
76
|
+
|
|
73
77
|
function _objectWithoutPropertiesLoose(source, excluded) {
|
|
74
78
|
if (source == null) return {};
|
|
75
79
|
var target = {};
|
|
@@ -107,27 +111,27 @@
|
|
|
107
111
|
}
|
|
108
112
|
|
|
109
113
|
function _toConsumableArray(arr) {
|
|
110
|
-
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
|
|
114
|
+
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray$1(arr) || _nonIterableSpread();
|
|
111
115
|
}
|
|
112
116
|
|
|
113
117
|
function _arrayWithoutHoles(arr) {
|
|
114
|
-
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
|
|
118
|
+
if (Array.isArray(arr)) return _arrayLikeToArray$1(arr);
|
|
115
119
|
}
|
|
116
120
|
|
|
117
121
|
function _iterableToArray(iter) {
|
|
118
|
-
if (typeof Symbol !== "undefined" && Symbol.iterator
|
|
122
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
119
123
|
}
|
|
120
124
|
|
|
121
|
-
function _unsupportedIterableToArray(o, minLen) {
|
|
125
|
+
function _unsupportedIterableToArray$1(o, minLen) {
|
|
122
126
|
if (!o) return;
|
|
123
|
-
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
|
|
127
|
+
if (typeof o === "string") return _arrayLikeToArray$1(o, minLen);
|
|
124
128
|
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
125
129
|
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
126
130
|
if (n === "Map" || n === "Set") return Array.from(o);
|
|
127
|
-
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
|
|
131
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$1(o, minLen);
|
|
128
132
|
}
|
|
129
133
|
|
|
130
|
-
function _arrayLikeToArray(arr, len) {
|
|
134
|
+
function _arrayLikeToArray$1(arr, len) {
|
|
131
135
|
if (len == null || len > arr.length) len = arr.length;
|
|
132
136
|
|
|
133
137
|
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
|
|
@@ -140,23 +144,23 @@
|
|
|
140
144
|
}
|
|
141
145
|
|
|
142
146
|
function _slicedToArray(arr, i) {
|
|
143
|
-
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray
|
|
147
|
+
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
|
|
144
148
|
}
|
|
145
149
|
|
|
146
150
|
function _nonIterableRest() {
|
|
147
151
|
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
148
152
|
}
|
|
149
153
|
|
|
150
|
-
function _unsupportedIterableToArray
|
|
154
|
+
function _unsupportedIterableToArray(o, minLen) {
|
|
151
155
|
if (!o) return;
|
|
152
|
-
if (typeof o === "string") return _arrayLikeToArray
|
|
156
|
+
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
|
|
153
157
|
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
154
158
|
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
155
159
|
if (n === "Map" || n === "Set") return Array.from(o);
|
|
156
|
-
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray
|
|
160
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
|
|
157
161
|
}
|
|
158
162
|
|
|
159
|
-
function _arrayLikeToArray
|
|
163
|
+
function _arrayLikeToArray(arr, len) {
|
|
160
164
|
if (len == null || len > arr.length) len = arr.length;
|
|
161
165
|
|
|
162
166
|
for (var i = 0, arr2 = new Array(len); i < len; i++) {
|
|
@@ -167,14 +171,17 @@
|
|
|
167
171
|
}
|
|
168
172
|
|
|
169
173
|
function _iterableToArrayLimit(arr, i) {
|
|
170
|
-
|
|
174
|
+
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
175
|
+
|
|
176
|
+
if (_i == null) return;
|
|
171
177
|
var _arr = [];
|
|
172
178
|
var _n = true;
|
|
173
179
|
var _d = false;
|
|
174
|
-
|
|
180
|
+
|
|
181
|
+
var _s, _e;
|
|
175
182
|
|
|
176
183
|
try {
|
|
177
|
-
for (
|
|
184
|
+
for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
|
|
178
185
|
_arr.push(_s.value);
|
|
179
186
|
|
|
180
187
|
if (i && _arr.length === i) break;
|
|
@@ -197,20 +204,20 @@
|
|
|
197
204
|
if (Array.isArray(arr)) return arr;
|
|
198
205
|
}
|
|
199
206
|
|
|
200
|
-
function _typeof
|
|
207
|
+
function _typeof(obj) {
|
|
201
208
|
"@babel/helpers - typeof";
|
|
202
209
|
|
|
203
210
|
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
|
|
204
|
-
_typeof
|
|
211
|
+
_typeof = function _typeof(obj) {
|
|
205
212
|
return typeof obj;
|
|
206
213
|
};
|
|
207
214
|
} else {
|
|
208
|
-
_typeof
|
|
215
|
+
_typeof = function _typeof(obj) {
|
|
209
216
|
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
|
|
210
217
|
};
|
|
211
218
|
}
|
|
212
219
|
|
|
213
|
-
return _typeof
|
|
220
|
+
return _typeof(obj);
|
|
214
221
|
}
|
|
215
222
|
/**
|
|
216
223
|
* Decycles objects with circular references.
|
|
@@ -221,7 +228,7 @@
|
|
|
221
228
|
function decycle(obj) {
|
|
222
229
|
var seen = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Set();
|
|
223
230
|
|
|
224
|
-
if (
|
|
231
|
+
if (!obj || _typeof(obj) !== 'object') {
|
|
225
232
|
return obj;
|
|
226
233
|
}
|
|
227
234
|
|
|
@@ -279,6 +286,15 @@
|
|
|
279
286
|
}
|
|
280
287
|
}
|
|
281
288
|
|
|
289
|
+
var noop = function noop() {};
|
|
290
|
+
|
|
291
|
+
var version = '1.5.1';
|
|
292
|
+
|
|
293
|
+
var userAgents = [{
|
|
294
|
+
segment: 'autocomplete-core',
|
|
295
|
+
version: version
|
|
296
|
+
}];
|
|
297
|
+
|
|
282
298
|
var warnCache = {
|
|
283
299
|
current: {}
|
|
284
300
|
};
|
|
@@ -325,7 +341,8 @@
|
|
|
325
341
|
state: state,
|
|
326
342
|
prevState: prevState
|
|
327
343
|
});
|
|
328
|
-
}
|
|
344
|
+
},
|
|
345
|
+
shouldSkipPendingUpdate: false
|
|
329
346
|
};
|
|
330
347
|
}
|
|
331
348
|
|
|
@@ -378,6 +395,55 @@
|
|
|
378
395
|
};
|
|
379
396
|
}
|
|
380
397
|
|
|
398
|
+
/**
|
|
399
|
+
* Creates a runner that executes promises in a concurrent-safe way.
|
|
400
|
+
*
|
|
401
|
+
* This is useful to prevent older promises to resolve after a newer promise,
|
|
402
|
+
* otherwise resulting in stale resolved values.
|
|
403
|
+
*/
|
|
404
|
+
function createConcurrentSafePromise() {
|
|
405
|
+
var basePromiseId = -1;
|
|
406
|
+
var latestResolvedId = -1;
|
|
407
|
+
var latestResolvedValue = undefined;
|
|
408
|
+
var runningPromisesCount = 0;
|
|
409
|
+
|
|
410
|
+
function runConcurrentSafePromise(promise) {
|
|
411
|
+
basePromiseId++;
|
|
412
|
+
runningPromisesCount++;
|
|
413
|
+
var currentPromiseId = basePromiseId;
|
|
414
|
+
return Promise.resolve(promise).then(function (x) {
|
|
415
|
+
// The promise might take too long to resolve and get outdated. This would
|
|
416
|
+
// result in resolving stale values.
|
|
417
|
+
// When this happens, we ignore the promise value and return the one
|
|
418
|
+
// coming from the latest resolved value.
|
|
419
|
+
//
|
|
420
|
+
// +----------------------------------+
|
|
421
|
+
// | 100ms |
|
|
422
|
+
// | run(1) +---> R1 |
|
|
423
|
+
// | 300ms |
|
|
424
|
+
// | run(2) +-------------> R2 (SKIP) |
|
|
425
|
+
// | 200ms |
|
|
426
|
+
// | run(3) +--------> R3 |
|
|
427
|
+
// +----------------------------------+
|
|
428
|
+
if (latestResolvedValue && currentPromiseId < latestResolvedId) {
|
|
429
|
+
return latestResolvedValue;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
latestResolvedId = currentPromiseId;
|
|
433
|
+
latestResolvedValue = x;
|
|
434
|
+
return x;
|
|
435
|
+
}).finally(function () {
|
|
436
|
+
return runningPromisesCount--;
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
runConcurrentSafePromise.isRunning = function () {
|
|
441
|
+
return runningPromisesCount > 0;
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
return runConcurrentSafePromise;
|
|
445
|
+
}
|
|
446
|
+
|
|
381
447
|
/**
|
|
382
448
|
* Returns the next active item ID from the current state.
|
|
383
449
|
*
|
|
@@ -412,13 +478,11 @@
|
|
|
412
478
|
return numericIndex;
|
|
413
479
|
}
|
|
414
480
|
|
|
415
|
-
var noop = function noop() {};
|
|
416
|
-
|
|
417
481
|
function getNormalizedSources(getSources, params) {
|
|
418
482
|
var seenSourceIds = [];
|
|
419
483
|
return Promise.resolve(getSources(params)).then(function (sources) {
|
|
420
484
|
invariant(Array.isArray(sources), function () {
|
|
421
|
-
return "The `getSources` function must return an array of sources but returned type ".concat(JSON.stringify(_typeof(sources)), ":\n\n").concat(JSON.stringify(decycle(sources), null, 2));
|
|
485
|
+
return "The `getSources` function must return an array of sources but returned type ".concat(JSON.stringify(_typeof$1(sources)), ":\n\n").concat(JSON.stringify(decycle(sources), null, 2));
|
|
422
486
|
});
|
|
423
487
|
return Promise.all(sources // We allow `undefined` and `false` sources to allow users to use
|
|
424
488
|
// `Boolean(query) && source` (=> `false`).
|
|
@@ -812,7 +876,7 @@
|
|
|
812
876
|
var transform = matches[0].transformResponse;
|
|
813
877
|
var items = transform ? transform(mapToAlgoliaResponse(results)) : results;
|
|
814
878
|
invariant(Array.isArray(items), function () {
|
|
815
|
-
return "The `getItems` function from source \"".concat(source.sourceId, "\" must return an array of items but returned type ").concat(JSON.stringify(_typeof(items)), ":\n\n").concat(JSON.stringify(decycle(items), null, 2), ".\n\nSee: https://www.algolia.com/doc/ui-libraries/autocomplete/core-concepts/sources/#param-getitems");
|
|
879
|
+
return "The `getItems` function from source \"".concat(source.sourceId, "\" must return an array of items but returned type ").concat(JSON.stringify(_typeof$1(items)), ":\n\n").concat(JSON.stringify(decycle(items), null, 2), ".\n\nSee: https://www.algolia.com/doc/ui-libraries/autocomplete/core-concepts/sources/#param-getitems");
|
|
816
880
|
});
|
|
817
881
|
invariant(items.every(Boolean), "The `getItems` function from source \"".concat(source.sourceId, "\" must return an array of items but returned ").concat(JSON.stringify(undefined), ".\n\nDid you forget to return items?\n\nSee: https://www.algolia.com/doc/ui-libraries/autocomplete/core-concepts/sources/#param-getitems"));
|
|
818
882
|
return {
|
|
@@ -822,7 +886,9 @@
|
|
|
822
886
|
});
|
|
823
887
|
}
|
|
824
888
|
|
|
889
|
+
var _excluded$2 = ["event", "nextState", "props", "query", "refresh", "store"];
|
|
825
890
|
var lastStalledId = null;
|
|
891
|
+
var runConcurrentSafePromise = createConcurrentSafePromise();
|
|
826
892
|
function onInput(_ref) {
|
|
827
893
|
var event = _ref.event,
|
|
828
894
|
_ref$nextState = _ref.nextState,
|
|
@@ -831,7 +897,7 @@
|
|
|
831
897
|
query = _ref.query,
|
|
832
898
|
refresh = _ref.refresh,
|
|
833
899
|
store = _ref.store,
|
|
834
|
-
setters = _objectWithoutProperties(_ref,
|
|
900
|
+
setters = _objectWithoutProperties(_ref, _excluded$2);
|
|
835
901
|
|
|
836
902
|
if (lastStalledId) {
|
|
837
903
|
props.environment.clearTimeout(lastStalledId);
|
|
@@ -848,28 +914,40 @@
|
|
|
848
914
|
if (!query && props.openOnFocus === false) {
|
|
849
915
|
var _nextState$isOpen;
|
|
850
916
|
|
|
851
|
-
|
|
852
|
-
setCollections(store.getState().collections.map(function (collection) {
|
|
917
|
+
var collections = store.getState().collections.map(function (collection) {
|
|
853
918
|
return _objectSpread2(_objectSpread2({}, collection), {}, {
|
|
854
919
|
items: []
|
|
855
920
|
});
|
|
856
|
-
})
|
|
921
|
+
});
|
|
922
|
+
setStatus('idle');
|
|
923
|
+
setCollections(collections);
|
|
857
924
|
setIsOpen((_nextState$isOpen = nextState.isOpen) !== null && _nextState$isOpen !== void 0 ? _nextState$isOpen : props.shouldPanelOpen({
|
|
858
925
|
state: store.getState()
|
|
859
|
-
}));
|
|
860
|
-
|
|
926
|
+
})); // We make sure to update the latest resolved value of the tracked
|
|
927
|
+
// promises to keep late resolving promises from "cancelling" the state
|
|
928
|
+
// updates performed in this code path.
|
|
929
|
+
// We chain with a void promise to respect `onInput`'s expected return type.
|
|
930
|
+
|
|
931
|
+
return runConcurrentSafePromise(collections).then(function () {
|
|
932
|
+
return Promise.resolve();
|
|
933
|
+
});
|
|
861
934
|
}
|
|
862
935
|
|
|
863
936
|
setStatus('loading');
|
|
864
937
|
lastStalledId = props.environment.setTimeout(function () {
|
|
865
938
|
setStatus('stalled');
|
|
866
|
-
}, props.stallThreshold);
|
|
867
|
-
|
|
939
|
+
}, props.stallThreshold); // We track the entire promise chain triggered by `onInput` before mutating
|
|
940
|
+
// the Autocomplete state to make sure that any state manipulation is based on
|
|
941
|
+
// fresh data regardless of when promises individually resolve.
|
|
942
|
+
// We don't track nested promises and only rely on the full chain resolution,
|
|
943
|
+
// meaning we should only ever manipulate the state once this concurrent-safe
|
|
944
|
+
// promise is resolved.
|
|
945
|
+
|
|
946
|
+
return runConcurrentSafePromise(props.getSources(_objectSpread2({
|
|
868
947
|
query: query,
|
|
869
948
|
refresh: refresh,
|
|
870
949
|
state: store.getState()
|
|
871
950
|
}, setters)).then(function (sources) {
|
|
872
|
-
setStatus('loading');
|
|
873
951
|
return Promise.all(sources.map(function (source) {
|
|
874
952
|
return Promise.resolve(source.getItems(_objectSpread2({
|
|
875
953
|
query: query,
|
|
@@ -886,46 +964,61 @@
|
|
|
886
964
|
props: props,
|
|
887
965
|
state: store.getState()
|
|
888
966
|
});
|
|
889
|
-
})
|
|
890
|
-
|
|
967
|
+
});
|
|
968
|
+
})).then(function (collections) {
|
|
969
|
+
var _nextState$isOpen2;
|
|
891
970
|
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
setIsOpen((_nextState$isOpen2 = nextState.isOpen) !== null && _nextState$isOpen2 !== void 0 ? _nextState$isOpen2 : props.openOnFocus && !query && isPanelOpen || isPanelOpen);
|
|
898
|
-
var highlightedItem = getActiveItem(store.getState());
|
|
971
|
+
// Parameters passed to `onInput` could be stale when the following code
|
|
972
|
+
// executes, because `onInput` calls may not resolve in order.
|
|
973
|
+
// If it becomes a problem we'll need to save the last passed parameters.
|
|
974
|
+
// See: https://codesandbox.io/s/agitated-cookies-y290z
|
|
975
|
+
setStatus('idle');
|
|
899
976
|
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
itemUrl = highlightedItem.itemUrl,
|
|
904
|
-
source = highlightedItem.source;
|
|
905
|
-
source.onActive(_objectSpread2({
|
|
906
|
-
event: event,
|
|
907
|
-
item: item,
|
|
908
|
-
itemInputValue: itemInputValue,
|
|
909
|
-
itemUrl: itemUrl,
|
|
910
|
-
refresh: refresh,
|
|
911
|
-
source: source,
|
|
912
|
-
state: store.getState()
|
|
913
|
-
}, setters));
|
|
914
|
-
}
|
|
915
|
-
}).finally(function () {
|
|
916
|
-
if (lastStalledId) {
|
|
917
|
-
props.environment.clearTimeout(lastStalledId);
|
|
977
|
+
if (store.shouldSkipPendingUpdate) {
|
|
978
|
+
if (!runConcurrentSafePromise.isRunning()) {
|
|
979
|
+
store.shouldSkipPendingUpdate = false;
|
|
918
980
|
}
|
|
981
|
+
|
|
982
|
+
return;
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
setCollections(collections);
|
|
986
|
+
var isPanelOpen = props.shouldPanelOpen({
|
|
987
|
+
state: store.getState()
|
|
919
988
|
});
|
|
989
|
+
setIsOpen((_nextState$isOpen2 = nextState.isOpen) !== null && _nextState$isOpen2 !== void 0 ? _nextState$isOpen2 : props.openOnFocus && !query && isPanelOpen || isPanelOpen);
|
|
990
|
+
var highlightedItem = getActiveItem(store.getState());
|
|
991
|
+
|
|
992
|
+
if (store.getState().activeItemId !== null && highlightedItem) {
|
|
993
|
+
var item = highlightedItem.item,
|
|
994
|
+
itemInputValue = highlightedItem.itemInputValue,
|
|
995
|
+
itemUrl = highlightedItem.itemUrl,
|
|
996
|
+
source = highlightedItem.source;
|
|
997
|
+
source.onActive(_objectSpread2({
|
|
998
|
+
event: event,
|
|
999
|
+
item: item,
|
|
1000
|
+
itemInputValue: itemInputValue,
|
|
1001
|
+
itemUrl: itemUrl,
|
|
1002
|
+
refresh: refresh,
|
|
1003
|
+
source: source,
|
|
1004
|
+
state: store.getState()
|
|
1005
|
+
}, setters));
|
|
1006
|
+
}
|
|
1007
|
+
}).finally(function () {
|
|
1008
|
+
if (lastStalledId) {
|
|
1009
|
+
props.environment.clearTimeout(lastStalledId);
|
|
1010
|
+
}
|
|
920
1011
|
});
|
|
921
1012
|
}
|
|
1013
|
+
onInput.isRunning = runConcurrentSafePromise.isRunning;
|
|
922
1014
|
|
|
1015
|
+
var _excluded$1 = ["event", "props", "refresh", "store"];
|
|
923
1016
|
function onKeyDown(_ref) {
|
|
924
1017
|
var event = _ref.event,
|
|
925
1018
|
props = _ref.props,
|
|
926
1019
|
refresh = _ref.refresh,
|
|
927
1020
|
store = _ref.store,
|
|
928
|
-
setters = _objectWithoutProperties(_ref,
|
|
1021
|
+
setters = _objectWithoutProperties(_ref, _excluded$1);
|
|
929
1022
|
|
|
930
1023
|
if (event.key === 'ArrowUp' || event.key === 'ArrowDown') {
|
|
931
1024
|
// eslint-disable-next-line no-inner-declarations
|
|
@@ -994,7 +1087,14 @@
|
|
|
994
1087
|
// from removing the query right away because we first want to close the
|
|
995
1088
|
// panel.
|
|
996
1089
|
event.preventDefault();
|
|
997
|
-
store.dispatch(event.key, null);
|
|
1090
|
+
store.dispatch(event.key, null); // Hitting the `Escape` key signals the end of a user interaction with the
|
|
1091
|
+
// autocomplete. At this point, we should ignore any requests that are still
|
|
1092
|
+
// running and could reopen the panel once they resolve, because that would
|
|
1093
|
+
// result in an unsolicited UI behavior.
|
|
1094
|
+
|
|
1095
|
+
if (onInput.isRunning()) {
|
|
1096
|
+
store.shouldSkipPendingUpdate = true;
|
|
1097
|
+
}
|
|
998
1098
|
} else if (event.key === 'Enter') {
|
|
999
1099
|
// No active item, so we let the browser handle the native `onSubmit` form
|
|
1000
1100
|
// event.
|
|
@@ -1091,17 +1191,22 @@
|
|
|
1091
1191
|
}
|
|
1092
1192
|
}
|
|
1093
1193
|
|
|
1194
|
+
var _excluded = ["props", "refresh", "store"],
|
|
1195
|
+
_excluded2 = ["inputElement", "formElement", "panelElement"],
|
|
1196
|
+
_excluded3 = ["inputElement"],
|
|
1197
|
+
_excluded4 = ["inputElement", "maxLength"],
|
|
1198
|
+
_excluded5 = ["item", "source"];
|
|
1094
1199
|
function getPropGetters(_ref) {
|
|
1095
1200
|
var props = _ref.props,
|
|
1096
1201
|
refresh = _ref.refresh,
|
|
1097
1202
|
store = _ref.store,
|
|
1098
|
-
setters = _objectWithoutProperties(_ref,
|
|
1203
|
+
setters = _objectWithoutProperties(_ref, _excluded);
|
|
1099
1204
|
|
|
1100
1205
|
var getEnvironmentProps = function getEnvironmentProps(providedProps) {
|
|
1101
1206
|
var inputElement = providedProps.inputElement,
|
|
1102
1207
|
formElement = providedProps.formElement,
|
|
1103
1208
|
panelElement = providedProps.panelElement,
|
|
1104
|
-
rest = _objectWithoutProperties(providedProps,
|
|
1209
|
+
rest = _objectWithoutProperties(providedProps, _excluded2);
|
|
1105
1210
|
|
|
1106
1211
|
return _objectSpread2({
|
|
1107
1212
|
// On touch devices, we do not rely on the native `blur` event of the
|
|
@@ -1109,19 +1214,34 @@
|
|
|
1109
1214
|
// outside of the autocomplete elements.
|
|
1110
1215
|
// This ensures a working experience on mobile because we blur the input
|
|
1111
1216
|
// on touch devices when the user starts scrolling (`touchmove`).
|
|
1217
|
+
// @TODO: support cases where there are multiple Autocomplete instances.
|
|
1218
|
+
// Right now, a second instance makes this computation return false.
|
|
1112
1219
|
onTouchStart: function onTouchStart(event) {
|
|
1113
|
-
|
|
1220
|
+
// The `onTouchStart` event shouldn't trigger the `blur` handler when
|
|
1221
|
+
// it's not an interaction with Autocomplete. We detect it with the
|
|
1222
|
+
// following heuristics:
|
|
1223
|
+
// - the panel is closed AND there are no running requests
|
|
1224
|
+
// (no interaction with the autocomplete, no future state updates)
|
|
1225
|
+
// - OR the touched target is the input element (should open the panel)
|
|
1226
|
+
var isNotAutocompleteInteraction = store.getState().isOpen === false && !onInput.isRunning();
|
|
1227
|
+
|
|
1228
|
+
if (isNotAutocompleteInteraction || event.target === inputElement) {
|
|
1114
1229
|
return;
|
|
1115
|
-
}
|
|
1116
|
-
// Right now, a second instance makes this computation return false.
|
|
1117
|
-
|
|
1230
|
+
}
|
|
1118
1231
|
|
|
1119
1232
|
var isTargetWithinAutocomplete = [formElement, panelElement].some(function (contextNode) {
|
|
1120
|
-
return isOrContainsNode(contextNode, event.target)
|
|
1233
|
+
return isOrContainsNode(contextNode, event.target);
|
|
1121
1234
|
});
|
|
1122
1235
|
|
|
1123
1236
|
if (isTargetWithinAutocomplete === false) {
|
|
1124
|
-
store.dispatch('blur', null);
|
|
1237
|
+
store.dispatch('blur', null); // If requests are still running when the user closes the panel, they
|
|
1238
|
+
// could reopen the panel once they resolve.
|
|
1239
|
+
// We want to prevent any subsequent query from reopening the panel
|
|
1240
|
+
// because it would result in an unsolicited UI behavior.
|
|
1241
|
+
|
|
1242
|
+
if (!props.debug && onInput.isRunning()) {
|
|
1243
|
+
store.shouldSkipPendingUpdate = true;
|
|
1244
|
+
}
|
|
1125
1245
|
}
|
|
1126
1246
|
},
|
|
1127
1247
|
// When scrolling on touch devices (mobiles, tablets, etc.), we want to
|
|
@@ -1149,8 +1269,8 @@
|
|
|
1149
1269
|
};
|
|
1150
1270
|
|
|
1151
1271
|
var getFormProps = function getFormProps(providedProps) {
|
|
1152
|
-
|
|
1153
|
-
rest = _objectWithoutProperties(providedProps,
|
|
1272
|
+
providedProps.inputElement;
|
|
1273
|
+
var rest = _objectWithoutProperties(providedProps, _excluded3);
|
|
1154
1274
|
|
|
1155
1275
|
return _objectSpread2({
|
|
1156
1276
|
action: '',
|
|
@@ -1202,11 +1322,11 @@
|
|
|
1202
1322
|
|
|
1203
1323
|
var isTouchDevice = ('ontouchstart' in props.environment);
|
|
1204
1324
|
|
|
1205
|
-
var _ref2 = providedProps || {}
|
|
1206
|
-
|
|
1207
|
-
_ref2$maxLength = _ref2.maxLength,
|
|
1325
|
+
var _ref2 = providedProps || {};
|
|
1326
|
+
_ref2.inputElement;
|
|
1327
|
+
var _ref2$maxLength = _ref2.maxLength,
|
|
1208
1328
|
maxLength = _ref2$maxLength === void 0 ? 512 : _ref2$maxLength,
|
|
1209
|
-
rest = _objectWithoutProperties(_ref2,
|
|
1329
|
+
rest = _objectWithoutProperties(_ref2, _excluded4);
|
|
1210
1330
|
|
|
1211
1331
|
var activeItem = getActiveItem(store.getState());
|
|
1212
1332
|
return _objectSpread2({
|
|
@@ -1247,7 +1367,14 @@
|
|
|
1247
1367
|
// We do rely on the `blur` event on touch devices.
|
|
1248
1368
|
// See explanation in `onTouchStart`.
|
|
1249
1369
|
if (!isTouchDevice) {
|
|
1250
|
-
store.dispatch('blur', null);
|
|
1370
|
+
store.dispatch('blur', null); // If requests are still running when the user closes the panel, they
|
|
1371
|
+
// could reopen the panel once they resolve.
|
|
1372
|
+
// We want to prevent any subsequent query from reopening the panel
|
|
1373
|
+
// because it would result in an unsolicited UI behavior.
|
|
1374
|
+
|
|
1375
|
+
if (!props.debug && onInput.isRunning()) {
|
|
1376
|
+
store.shouldSkipPendingUpdate = true;
|
|
1377
|
+
}
|
|
1251
1378
|
}
|
|
1252
1379
|
},
|
|
1253
1380
|
onClick: function onClick(event) {
|
|
@@ -1297,7 +1424,7 @@
|
|
|
1297
1424
|
var getItemProps = function getItemProps(providedProps) {
|
|
1298
1425
|
var item = providedProps.item,
|
|
1299
1426
|
source = providedProps.source,
|
|
1300
|
-
rest = _objectWithoutProperties(providedProps,
|
|
1427
|
+
rest = _objectWithoutProperties(providedProps, _excluded5);
|
|
1301
1428
|
|
|
1302
1429
|
return _objectSpread2({
|
|
1303
1430
|
id: "".concat(props.id, "-item-").concat(item.__autocomplete_id),
|
|
@@ -1384,6 +1511,44 @@
|
|
|
1384
1511
|
};
|
|
1385
1512
|
}
|
|
1386
1513
|
|
|
1514
|
+
function getMetadata(_ref) {
|
|
1515
|
+
var _, _options$__autocomple, _options$__autocomple2, _options$__autocomple3;
|
|
1516
|
+
|
|
1517
|
+
var plugins = _ref.plugins,
|
|
1518
|
+
options = _ref.options;
|
|
1519
|
+
var optionsKey = (_ = (((_options$__autocomple = options.__autocomplete_metadata) === null || _options$__autocomple === void 0 ? void 0 : _options$__autocomple.userAgents) || [])[0]) === null || _ === void 0 ? void 0 : _.segment;
|
|
1520
|
+
var extraOptions = optionsKey ? _defineProperty({}, optionsKey, Object.keys(((_options$__autocomple2 = options.__autocomplete_metadata) === null || _options$__autocomple2 === void 0 ? void 0 : _options$__autocomple2.options) || {})) : {};
|
|
1521
|
+
return {
|
|
1522
|
+
plugins: plugins.map(function (plugin) {
|
|
1523
|
+
return {
|
|
1524
|
+
name: plugin.name,
|
|
1525
|
+
options: Object.keys(plugin.__autocomplete_pluginOptions || [])
|
|
1526
|
+
};
|
|
1527
|
+
}),
|
|
1528
|
+
options: _objectSpread2({
|
|
1529
|
+
'autocomplete-core': Object.keys(options)
|
|
1530
|
+
}, extraOptions),
|
|
1531
|
+
ua: userAgents.concat(((_options$__autocomple3 = options.__autocomplete_metadata) === null || _options$__autocomple3 === void 0 ? void 0 : _options$__autocomple3.userAgents) || [])
|
|
1532
|
+
};
|
|
1533
|
+
}
|
|
1534
|
+
function injectMetadata(_ref3) {
|
|
1535
|
+
var _environment$navigato;
|
|
1536
|
+
|
|
1537
|
+
var metadata = _ref3.metadata,
|
|
1538
|
+
environment = _ref3.environment;
|
|
1539
|
+
var isMetadataEnabled = (_environment$navigato = environment.navigator) === null || _environment$navigato === void 0 ? void 0 : _environment$navigato.userAgent.includes('Algolia Crawler');
|
|
1540
|
+
|
|
1541
|
+
if (isMetadataEnabled) {
|
|
1542
|
+
var metadataContainer = environment.document.createElement('meta');
|
|
1543
|
+
var headRef = environment.document.querySelector('head');
|
|
1544
|
+
metadataContainer.name = 'algolia:metadata';
|
|
1545
|
+
setTimeout(function () {
|
|
1546
|
+
metadataContainer.content = JSON.stringify(metadata);
|
|
1547
|
+
headRef.appendChild(metadataContainer);
|
|
1548
|
+
}, 0);
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
|
|
1387
1552
|
function getCompletion(_ref) {
|
|
1388
1553
|
var _getActiveItem;
|
|
1389
1554
|
|
|
@@ -1603,18 +1768,22 @@
|
|
|
1603
1768
|
}
|
|
1604
1769
|
}));
|
|
1605
1770
|
});
|
|
1771
|
+
injectMetadata({
|
|
1772
|
+
metadata: getMetadata({
|
|
1773
|
+
plugins: props.plugins,
|
|
1774
|
+
options: options
|
|
1775
|
+
}),
|
|
1776
|
+
environment: props.environment
|
|
1777
|
+
});
|
|
1606
1778
|
return _objectSpread2(_objectSpread2({
|
|
1607
1779
|
refresh: refresh
|
|
1608
1780
|
}, propGetters), setters);
|
|
1609
1781
|
}
|
|
1610
1782
|
|
|
1611
|
-
var version = '1.3.0';
|
|
1612
|
-
|
|
1613
1783
|
exports.createAutocomplete = createAutocomplete;
|
|
1614
1784
|
exports.getDefaultProps = getDefaultProps;
|
|
1615
|
-
exports.version = version;
|
|
1616
1785
|
|
|
1617
1786
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
1618
1787
|
|
|
1619
|
-
}))
|
|
1788
|
+
}));
|
|
1620
1789
|
//# sourceMappingURL=index.development.js.map
|