@nanoporetech-digital/components 5.2.0 → 5.3.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.
Files changed (263) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/cjs/{_commonjsHelpers-9f2314fc.js → _commonjsHelpers-29614748.js} +1 -17
  3. package/dist/cjs/_commonjsHelpers-29614748.js.map +1 -0
  4. package/dist/cjs/algoliasearch-lite.esm.browser-992a2eff.js +922 -0
  5. package/dist/cjs/algoliasearch-lite.esm.browser-992a2eff.js.map +1 -0
  6. package/dist/cjs/component-store-21cb4901.js +328 -0
  7. package/dist/cjs/component-store-21cb4901.js.map +1 -0
  8. package/dist/cjs/events-db0a42ee.js +39 -0
  9. package/dist/cjs/events-db0a42ee.js.map +1 -0
  10. package/dist/cjs/loader.cjs.js +1 -1
  11. package/dist/cjs/nano-alert.cjs.entry.js +9 -2
  12. package/dist/cjs/nano-alert.cjs.entry.js.map +1 -1
  13. package/dist/cjs/nano-algolia-filter.cjs.entry.js +1 -2
  14. package/dist/cjs/nano-algolia-filter.cjs.entry.js.map +1 -1
  15. package/dist/cjs/nano-algolia-input.cjs.entry.js +8 -4
  16. package/dist/cjs/nano-algolia-input.cjs.entry.js.map +1 -1
  17. package/dist/cjs/nano-algolia.cjs.entry.js +4 -4
  18. package/dist/cjs/nano-algolia.cjs.entry.js.map +1 -1
  19. package/dist/cjs/nano-components.cjs.js +1 -1
  20. package/dist/cjs/nano-datalist_3.cjs.entry.js +1 -1
  21. package/dist/cjs/nano-dialog.cjs.entry.js +23 -22
  22. package/dist/cjs/nano-dialog.cjs.entry.js.map +1 -1
  23. package/dist/cjs/nano-drawer.cjs.entry.js +169 -111
  24. package/dist/cjs/nano-drawer.cjs.entry.js.map +1 -1
  25. package/dist/cjs/nano-dropdown.cjs.entry.js +16 -2
  26. package/dist/cjs/nano-dropdown.cjs.entry.js.map +1 -1
  27. package/dist/cjs/nano-global-nav.cjs.entry.js +5 -6
  28. package/dist/cjs/nano-global-nav.cjs.entry.js.map +1 -1
  29. package/dist/cjs/nano-global-search-results.cjs.entry.js +2 -1
  30. package/dist/cjs/nano-global-search-results.cjs.entry.js.map +1 -1
  31. package/dist/cjs/nano-slides.cjs.entry.js +1 -1
  32. package/dist/cjs/nano-sortable.cjs.entry.js +3 -15
  33. package/dist/cjs/nano-sortable.cjs.entry.js.map +1 -1
  34. package/dist/cjs/nano-sticker.cjs.entry.js +16 -9
  35. package/dist/cjs/nano-sticker.cjs.entry.js.map +1 -1
  36. package/dist/cjs/nano-tab-group.cjs.entry.js +1 -2
  37. package/dist/cjs/nano-tab-group.cjs.entry.js.map +1 -1
  38. package/dist/cjs/{nano-table-04993bb4.js → nano-table-e15cc6b0.js} +16 -15
  39. package/dist/cjs/nano-table-e15cc6b0.js.map +1 -0
  40. package/dist/cjs/nano-table.cjs.entry.js +1 -1
  41. package/dist/cjs/{slot-a448c1a7.js → slot-2dd6ed1d.js} +20 -15
  42. package/dist/cjs/slot-2dd6ed1d.js.map +1 -0
  43. package/dist/cjs/{table.worker-85877b23.js → table.worker-8759e6ea.js} +2 -2
  44. package/dist/cjs/table.worker-8759e6ea.js.map +1 -0
  45. package/dist/collection/components/alert/alert.css +15 -0
  46. package/dist/collection/components/alert/alert.js +10 -2
  47. package/dist/collection/components/alert/alert.js.map +1 -1
  48. package/dist/collection/components/algolia/algolia-interface.js.map +1 -1
  49. package/dist/collection/components/algolia/algolia.js +1 -1
  50. package/dist/collection/components/algolia/algolia.js.map +1 -1
  51. package/dist/collection/components/dialog/dialog.css +1 -17
  52. package/dist/collection/components/dialog/dialog.js +31 -20
  53. package/dist/collection/components/dialog/dialog.js.map +1 -1
  54. package/dist/collection/components/drawer/drawer.css +136 -67
  55. package/dist/collection/components/drawer/drawer.js +282 -154
  56. package/dist/collection/components/drawer/drawer.js.map +1 -1
  57. package/dist/collection/components/dropdown/dropdown.css +10 -0
  58. package/dist/collection/components/dropdown/dropdown.js +15 -1
  59. package/dist/collection/components/dropdown/dropdown.js.map +1 -1
  60. package/dist/collection/components/global-nav/global-nav.js +2 -2
  61. package/dist/collection/components/global-nav/global-nav.js.map +1 -1
  62. package/dist/collection/components/global-nav/style/global-nav.css +5 -1
  63. package/dist/collection/components/global-search-results/global-search-results.js +2 -1
  64. package/dist/collection/components/global-search-results/global-search-results.js.map +1 -1
  65. package/dist/collection/components/sticker/sticker.js +16 -9
  66. package/dist/collection/components/sticker/sticker.js.map +1 -1
  67. package/dist/collection/components/table/table.js +10 -9
  68. package/dist/collection/components/table/table.js.map +1 -1
  69. package/dist/collection/components/table/table.pin-service.js +4 -4
  70. package/dist/collection/components/table/table.pin-service.js.map +1 -1
  71. package/dist/collection/utils/events.js +17 -0
  72. package/dist/collection/utils/events.js.map +1 -1
  73. package/dist/collection/utils/slot.js +19 -14
  74. package/dist/collection/utils/slot.js.map +1 -1
  75. package/dist/collection/utils/store/get-set.js +6 -12
  76. package/dist/collection/utils/store/get-set.js.map +1 -1
  77. package/dist/components/_commonjsHelpers.js +1 -16
  78. package/dist/components/_commonjsHelpers.js.map +1 -1
  79. package/dist/components/algolia.js +2 -2
  80. package/dist/components/algolia.js.map +1 -1
  81. package/dist/components/algoliasearch-lite.esm.browser.js +920 -0
  82. package/dist/components/algoliasearch-lite.esm.browser.js.map +1 -0
  83. package/dist/components/component-store.js +68 -2001
  84. package/dist/components/component-store.js.map +1 -1
  85. package/dist/components/dropdown.js +16 -2
  86. package/dist/components/dropdown.js.map +1 -1
  87. package/dist/components/events.js +36 -0
  88. package/dist/components/events.js.map +1 -0
  89. package/dist/components/nano-alert.js +10 -2
  90. package/dist/components/nano-alert.js.map +1 -1
  91. package/dist/components/nano-algolia-input.js +6 -1
  92. package/dist/components/nano-algolia-input.js.map +1 -1
  93. package/dist/components/nano-dialog.js +21 -20
  94. package/dist/components/nano-dialog.js.map +1 -1
  95. package/dist/components/nano-drawer.js +205 -122
  96. package/dist/components/nano-drawer.js.map +1 -1
  97. package/dist/components/nano-global-nav.js +4 -4
  98. package/dist/components/nano-global-nav.js.map +1 -1
  99. package/dist/components/nano-global-search-results.js +2 -1
  100. package/dist/components/nano-global-search-results.js.map +1 -1
  101. package/dist/components/nano-sortable.js +1 -13
  102. package/dist/components/nano-sortable.js.map +1 -1
  103. package/dist/components/slot.js +19 -14
  104. package/dist/components/slot.js.map +1 -1
  105. package/dist/components/sticker.js +16 -9
  106. package/dist/components/sticker.js.map +1 -1
  107. package/dist/components/table.js +14 -13
  108. package/dist/components/table.js.map +1 -1
  109. package/dist/esm/{_commonjsHelpers-e401b2a2.js → _commonjsHelpers-04a0e019.js} +2 -17
  110. package/dist/esm/_commonjsHelpers-04a0e019.js.map +1 -0
  111. package/dist/esm/algoliasearch-lite.esm.browser-04891fdc.js +920 -0
  112. package/dist/esm/algoliasearch-lite.esm.browser-04891fdc.js.map +1 -0
  113. package/dist/esm/component-store-65d7e36a.js +326 -0
  114. package/dist/esm/component-store-65d7e36a.js.map +1 -0
  115. package/dist/esm/events-6a805b42.js +36 -0
  116. package/dist/esm/events-6a805b42.js.map +1 -0
  117. package/dist/esm/loader.js +1 -1
  118. package/dist/esm/nano-alert.entry.js +9 -2
  119. package/dist/esm/nano-alert.entry.js.map +1 -1
  120. package/dist/esm/nano-algolia-filter.entry.js +1 -2
  121. package/dist/esm/nano-algolia-filter.entry.js.map +1 -1
  122. package/dist/esm/nano-algolia-input.entry.js +7 -3
  123. package/dist/esm/nano-algolia-input.entry.js.map +1 -1
  124. package/dist/esm/nano-algolia.entry.js +4 -4
  125. package/dist/esm/nano-algolia.entry.js.map +1 -1
  126. package/dist/esm/nano-components.js +1 -1
  127. package/dist/esm/nano-datalist_3.entry.js +1 -1
  128. package/dist/esm/nano-dialog.entry.js +23 -22
  129. package/dist/esm/nano-dialog.entry.js.map +1 -1
  130. package/dist/esm/nano-drawer.entry.js +171 -113
  131. package/dist/esm/nano-drawer.entry.js.map +1 -1
  132. package/dist/esm/nano-dropdown.entry.js +16 -2
  133. package/dist/esm/nano-dropdown.entry.js.map +1 -1
  134. package/dist/esm/nano-global-nav.entry.js +5 -6
  135. package/dist/esm/nano-global-nav.entry.js.map +1 -1
  136. package/dist/esm/nano-global-search-results.entry.js +2 -1
  137. package/dist/esm/nano-global-search-results.entry.js.map +1 -1
  138. package/dist/esm/nano-slides.entry.js +1 -1
  139. package/dist/esm/nano-sortable.entry.js +1 -13
  140. package/dist/esm/nano-sortable.entry.js.map +1 -1
  141. package/dist/esm/nano-sticker.entry.js +16 -9
  142. package/dist/esm/nano-sticker.entry.js.map +1 -1
  143. package/dist/esm/nano-tab-group.entry.js +1 -2
  144. package/dist/esm/nano-tab-group.entry.js.map +1 -1
  145. package/dist/esm/{nano-table-91f09583.js → nano-table-5c5bd3f2.js} +16 -15
  146. package/dist/esm/nano-table-5c5bd3f2.js.map +1 -0
  147. package/dist/esm/nano-table.entry.js +1 -1
  148. package/dist/esm/{slot-a4f6e2af.js → slot-8126e238.js} +20 -15
  149. package/dist/esm/slot-8126e238.js.map +1 -0
  150. package/dist/esm/{table.worker-625475ba.js → table.worker-e7f4f50c.js} +2 -2
  151. package/dist/esm/table.worker-e7f4f50c.js.map +1 -0
  152. package/dist/nano-components/nano-components.css +1 -1
  153. package/dist/nano-components/nano-components.esm.js +1 -1
  154. package/dist/nano-components/nano-components.esm.js.map +1 -1
  155. package/dist/nano-components/p-0301e8f7.entry.js +5 -0
  156. package/dist/nano-components/p-0301e8f7.entry.js.map +1 -0
  157. package/dist/nano-components/p-27422aa9.entry.js +5 -0
  158. package/dist/nano-components/{p-6920ad69.entry.js.map → p-27422aa9.entry.js.map} +1 -1
  159. package/dist/nano-components/p-2d79f5b3.js +5 -0
  160. package/dist/nano-components/{p-0697795a.entry.js → p-31c23d6e.entry.js} +2 -2
  161. package/dist/nano-components/p-31c23d6e.entry.js.map +1 -0
  162. package/dist/nano-components/p-487de04d.entry.js.map +1 -1
  163. package/dist/nano-components/p-570d2e50.entry.js +5 -0
  164. package/dist/nano-components/p-570d2e50.entry.js.map +1 -0
  165. package/dist/nano-components/{p-3eb6d833.entry.js → p-5a4b3fa9.entry.js} +2 -2
  166. package/dist/nano-components/p-653ae985.js +5 -0
  167. package/dist/nano-components/p-653ae985.js.map +1 -0
  168. package/dist/nano-components/p-676a4744.entry.js +5 -0
  169. package/dist/nano-components/{p-d0eefd52.entry.js.map → p-676a4744.entry.js.map} +1 -1
  170. package/dist/nano-components/p-8fe51abf.js +5 -0
  171. package/dist/nano-components/{p-4884b65a.entry.js → p-90cd4f56.entry.js} +2 -2
  172. package/dist/nano-components/p-90cd4f56.entry.js.map +1 -0
  173. package/dist/nano-components/p-9ba81ed2.js +5 -0
  174. package/dist/nano-components/p-9ba81ed2.js.map +1 -0
  175. package/dist/nano-components/p-9bfdee71.js +5 -0
  176. package/dist/nano-components/p-9bfdee71.js.map +1 -0
  177. package/dist/nano-components/p-a8d6ca38.entry.js +5 -0
  178. package/dist/nano-components/p-a8d6ca38.entry.js.map +1 -0
  179. package/dist/nano-components/p-ace7743c.entry.js +5 -0
  180. package/dist/nano-components/p-ace7743c.entry.js.map +1 -0
  181. package/dist/nano-components/{p-17ee0c07.entry.js → p-bab2888b.entry.js} +2 -2
  182. package/dist/nano-components/p-bdb5b6fc.entry.js +5 -0
  183. package/dist/nano-components/p-bdb5b6fc.entry.js.map +1 -0
  184. package/dist/nano-components/p-cad86fb8.js +5 -0
  185. package/dist/nano-components/p-cad86fb8.js.map +1 -0
  186. package/dist/nano-components/p-dc565459.js +5 -0
  187. package/dist/nano-components/p-dc565459.js.map +1 -0
  188. package/dist/nano-components/p-ede12d35.entry.js +5 -0
  189. package/dist/nano-components/p-ede12d35.entry.js.map +1 -0
  190. package/dist/nano-components/p-f504b1df.entry.js +7 -0
  191. package/dist/nano-components/p-f504b1df.entry.js.map +1 -0
  192. package/dist/nano-components/{p-db370094.entry.js → p-f7a4c62b.entry.js} +2 -2
  193. package/dist/themes/london-calling.css.map +1 -1
  194. package/dist/themes/nanopore.cn.css.map +1 -1
  195. package/dist/themes/nanopore.css.map +1 -1
  196. package/dist/types/components/alert/alert.d.ts +1 -0
  197. package/dist/types/components/algolia/algolia-interface.d.ts +1 -1
  198. package/dist/types/components/algolia/algolia.d.ts +1 -1
  199. package/dist/types/components/dialog/dialog.d.ts +15 -4
  200. package/dist/types/components/drawer/drawer.d.ts +69 -50
  201. package/dist/types/components/sticker/sticker.d.ts +4 -4
  202. package/dist/types/components/table/table.d.ts +0 -1
  203. package/dist/types/components.d.ts +50 -28
  204. package/dist/types/types/algolia.d.ts +4 -0
  205. package/dist/types/types/scss.vars.d.ts +4 -0
  206. package/dist/types/utils/events.d.ts +7 -0
  207. package/dist/types/utils/slot.d.ts +3 -3
  208. package/docs-json.json +268 -61
  209. package/docs-vscode.json +28 -11
  210. package/hydrate/index.js +1345 -2245
  211. package/package.json +4 -4
  212. package/dist/cjs/_commonjsHelpers-9f2314fc.js.map +0 -1
  213. package/dist/cjs/algoliasearch.umd-689c1560.js +0 -15
  214. package/dist/cjs/algoliasearch.umd-689c1560.js.map +0 -1
  215. package/dist/cjs/component-store-f1dc1276.js +0 -2261
  216. package/dist/cjs/component-store-f1dc1276.js.map +0 -1
  217. package/dist/cjs/nano-table-04993bb4.js.map +0 -1
  218. package/dist/cjs/slot-a448c1a7.js.map +0 -1
  219. package/dist/cjs/table.worker-85877b23.js.map +0 -1
  220. package/dist/components/algoliasearch.umd.js +0 -13
  221. package/dist/components/algoliasearch.umd.js.map +0 -1
  222. package/dist/esm/_commonjsHelpers-e401b2a2.js.map +0 -1
  223. package/dist/esm/algoliasearch.umd-4f7efa84.js +0 -13
  224. package/dist/esm/algoliasearch.umd-4f7efa84.js.map +0 -1
  225. package/dist/esm/component-store-c23ebc9c.js +0 -2259
  226. package/dist/esm/component-store-c23ebc9c.js.map +0 -1
  227. package/dist/esm/nano-table-91f09583.js.map +0 -1
  228. package/dist/esm/slot-a4f6e2af.js.map +0 -1
  229. package/dist/esm/table.worker-625475ba.js.map +0 -1
  230. package/dist/nano-components/p-0697795a.entry.js.map +0 -1
  231. package/dist/nano-components/p-17b099cc.entry.js +0 -5
  232. package/dist/nano-components/p-17b099cc.entry.js.map +0 -1
  233. package/dist/nano-components/p-1a0b5bc3.js +0 -5
  234. package/dist/nano-components/p-1a0b5bc3.js.map +0 -1
  235. package/dist/nano-components/p-3de3449e.js +0 -5
  236. package/dist/nano-components/p-3de3449e.js.map +0 -1
  237. package/dist/nano-components/p-4884b65a.entry.js.map +0 -1
  238. package/dist/nano-components/p-58cf5446.js +0 -5
  239. package/dist/nano-components/p-58cf5446.js.map +0 -1
  240. package/dist/nano-components/p-6920ad69.entry.js +0 -5
  241. package/dist/nano-components/p-69a3e911.js +0 -5
  242. package/dist/nano-components/p-7baa9e14.entry.js +0 -5
  243. package/dist/nano-components/p-7baa9e14.entry.js.map +0 -1
  244. package/dist/nano-components/p-a362bd23.entry.js +0 -5
  245. package/dist/nano-components/p-a362bd23.entry.js.map +0 -1
  246. package/dist/nano-components/p-b04fd7ca.entry.js +0 -5
  247. package/dist/nano-components/p-b04fd7ca.entry.js.map +0 -1
  248. package/dist/nano-components/p-b72df1aa.entry.js +0 -5
  249. package/dist/nano-components/p-b72df1aa.entry.js.map +0 -1
  250. package/dist/nano-components/p-ce5efc3f.entry.js +0 -5
  251. package/dist/nano-components/p-ce5efc3f.entry.js.map +0 -1
  252. package/dist/nano-components/p-d0eefd52.entry.js +0 -5
  253. package/dist/nano-components/p-dfbf0d56.js +0 -5
  254. package/dist/nano-components/p-e2b2b015.entry.js +0 -5
  255. package/dist/nano-components/p-e2b2b015.entry.js.map +0 -1
  256. package/dist/nano-components/p-ed6adde2.js +0 -7
  257. package/dist/nano-components/p-ed6adde2.js.map +0 -1
  258. package/dist/types/dom.ie.d.ts +0 -3
  259. /package/dist/nano-components/{p-17ee0c07.entry.js.map → p-2d79f5b3.js.map} +0 -0
  260. /package/dist/nano-components/{p-3eb6d833.entry.js.map → p-5a4b3fa9.entry.js.map} +0 -0
  261. /package/dist/nano-components/{p-69a3e911.js.map → p-8fe51abf.js.map} +0 -0
  262. /package/dist/nano-components/{p-dfbf0d56.js.map → p-bab2888b.entry.js.map} +0 -0
  263. /package/dist/nano-components/{p-db370094.entry.js.map → p-f7a4c62b.entry.js.map} +0 -0
@@ -0,0 +1,920 @@
1
+ /*!
2
+ * Web Components for Nanopore digital Web Apps
3
+ */
4
+ function createBrowserLocalStorageCache(options) {
5
+ const namespaceKey = `algoliasearch-client-js-${options.key}`;
6
+ // eslint-disable-next-line functional/no-let
7
+ let storage;
8
+ const getStorage = () => {
9
+ if (storage === undefined) {
10
+ storage = options.localStorage || window.localStorage;
11
+ }
12
+ return storage;
13
+ };
14
+ const getNamespace = () => {
15
+ return JSON.parse(getStorage().getItem(namespaceKey) || '{}');
16
+ };
17
+ return {
18
+ get(key, defaultValue, events = {
19
+ miss: () => Promise.resolve(),
20
+ }) {
21
+ return Promise.resolve()
22
+ .then(() => {
23
+ const keyAsString = JSON.stringify(key);
24
+ const value = getNamespace()[keyAsString];
25
+ return Promise.all([value || defaultValue(), value !== undefined]);
26
+ })
27
+ .then(([value, exists]) => {
28
+ return Promise.all([value, exists || events.miss(value)]);
29
+ })
30
+ .then(([value]) => value);
31
+ },
32
+ set(key, value) {
33
+ return Promise.resolve().then(() => {
34
+ const namespace = getNamespace();
35
+ // eslint-disable-next-line functional/immutable-data
36
+ namespace[JSON.stringify(key)] = value;
37
+ getStorage().setItem(namespaceKey, JSON.stringify(namespace));
38
+ return value;
39
+ });
40
+ },
41
+ delete(key) {
42
+ return Promise.resolve().then(() => {
43
+ const namespace = getNamespace();
44
+ // eslint-disable-next-line functional/immutable-data
45
+ delete namespace[JSON.stringify(key)];
46
+ getStorage().setItem(namespaceKey, JSON.stringify(namespace));
47
+ });
48
+ },
49
+ clear() {
50
+ return Promise.resolve().then(() => {
51
+ getStorage().removeItem(namespaceKey);
52
+ });
53
+ },
54
+ };
55
+ }
56
+
57
+ // @todo Add logger on options to debug when caches go wrong.
58
+ function createFallbackableCache(options) {
59
+ const caches = [...options.caches];
60
+ const current = caches.shift(); // eslint-disable-line functional/immutable-data
61
+ if (current === undefined) {
62
+ return createNullCache();
63
+ }
64
+ return {
65
+ get(key, defaultValue, events = {
66
+ miss: () => Promise.resolve(),
67
+ }) {
68
+ return current.get(key, defaultValue, events).catch(() => {
69
+ return createFallbackableCache({ caches }).get(key, defaultValue, events);
70
+ });
71
+ },
72
+ set(key, value) {
73
+ return current.set(key, value).catch(() => {
74
+ return createFallbackableCache({ caches }).set(key, value);
75
+ });
76
+ },
77
+ delete(key) {
78
+ return current.delete(key).catch(() => {
79
+ return createFallbackableCache({ caches }).delete(key);
80
+ });
81
+ },
82
+ clear() {
83
+ return current.clear().catch(() => {
84
+ return createFallbackableCache({ caches }).clear();
85
+ });
86
+ },
87
+ };
88
+ }
89
+
90
+ function createNullCache() {
91
+ return {
92
+ get(_key, defaultValue, events = {
93
+ miss: () => Promise.resolve(),
94
+ }) {
95
+ const value = defaultValue();
96
+ return value
97
+ .then(result => Promise.all([result, events.miss(result)]))
98
+ .then(([result]) => result);
99
+ },
100
+ set(_key, value) {
101
+ return Promise.resolve(value);
102
+ },
103
+ delete(_key) {
104
+ return Promise.resolve();
105
+ },
106
+ clear() {
107
+ return Promise.resolve();
108
+ },
109
+ };
110
+ }
111
+
112
+ function createInMemoryCache(options = { serializable: true }) {
113
+ // eslint-disable-next-line functional/no-let
114
+ let cache = {};
115
+ return {
116
+ get(key, defaultValue, events = {
117
+ miss: () => Promise.resolve(),
118
+ }) {
119
+ const keyAsString = JSON.stringify(key);
120
+ if (keyAsString in cache) {
121
+ return Promise.resolve(options.serializable ? JSON.parse(cache[keyAsString]) : cache[keyAsString]);
122
+ }
123
+ const promise = defaultValue();
124
+ const miss = (events && events.miss) || (() => Promise.resolve());
125
+ return promise.then((value) => miss(value)).then(() => promise);
126
+ },
127
+ set(key, value) {
128
+ // eslint-disable-next-line functional/immutable-data
129
+ cache[JSON.stringify(key)] = options.serializable ? JSON.stringify(value) : value;
130
+ return Promise.resolve(value);
131
+ },
132
+ delete(key) {
133
+ // eslint-disable-next-line functional/immutable-data
134
+ delete cache[JSON.stringify(key)];
135
+ return Promise.resolve();
136
+ },
137
+ clear() {
138
+ cache = {};
139
+ return Promise.resolve();
140
+ },
141
+ };
142
+ }
143
+
144
+ function createAuth(authMode, appId, apiKey) {
145
+ const credentials = {
146
+ 'x-algolia-api-key': apiKey,
147
+ 'x-algolia-application-id': appId,
148
+ };
149
+ return {
150
+ headers() {
151
+ return authMode === AuthMode.WithinHeaders ? credentials : {};
152
+ },
153
+ queryParameters() {
154
+ return authMode === AuthMode.WithinQueryParameters ? credentials : {};
155
+ },
156
+ };
157
+ }
158
+
159
+ // eslint-disable-next-line functional/prefer-readonly-type
160
+ function shuffle(array) {
161
+ let c = array.length - 1; // eslint-disable-line functional/no-let
162
+ // eslint-disable-next-line functional/no-loop-statement
163
+ for (c; c > 0; c--) {
164
+ const b = Math.floor(Math.random() * (c + 1));
165
+ const a = array[c];
166
+ array[c] = array[b]; // eslint-disable-line functional/immutable-data, no-param-reassign
167
+ array[b] = a; // eslint-disable-line functional/immutable-data, no-param-reassign
168
+ }
169
+ return array;
170
+ }
171
+ function addMethods(base, methods) {
172
+ if (!methods) {
173
+ return base;
174
+ }
175
+ Object.keys(methods).forEach(key => {
176
+ // eslint-disable-next-line functional/immutable-data, no-param-reassign
177
+ base[key] = methods[key](base);
178
+ });
179
+ return base;
180
+ }
181
+ function encode(format, ...args) {
182
+ // eslint-disable-next-line functional/no-let
183
+ let i = 0;
184
+ return format.replace(/%s/g, () => encodeURIComponent(args[i++]));
185
+ }
186
+
187
+ const version = '4.14.3';
188
+
189
+ const AuthMode = {
190
+ /**
191
+ * If auth credentials should be in query parameters.
192
+ */
193
+ WithinQueryParameters: 0,
194
+ /**
195
+ * If auth credentials should be in headers.
196
+ */
197
+ WithinHeaders: 1,
198
+ };
199
+
200
+ function createMappedRequestOptions(requestOptions, timeout) {
201
+ const options = requestOptions || {};
202
+ const data = options.data || {};
203
+ Object.keys(options).forEach(key => {
204
+ if (['timeout', 'headers', 'queryParameters', 'data', 'cacheable'].indexOf(key) === -1) {
205
+ data[key] = options[key]; // eslint-disable-line functional/immutable-data
206
+ }
207
+ });
208
+ return {
209
+ data: Object.entries(data).length > 0 ? data : undefined,
210
+ timeout: options.timeout || timeout,
211
+ headers: options.headers || {},
212
+ queryParameters: options.queryParameters || {},
213
+ cacheable: options.cacheable,
214
+ };
215
+ }
216
+
217
+ const CallEnum = {
218
+ /**
219
+ * If the host is read only.
220
+ */
221
+ Read: 1,
222
+ /**
223
+ * If the host is write only.
224
+ */
225
+ Write: 2,
226
+ /**
227
+ * If the host is both read and write.
228
+ */
229
+ Any: 3,
230
+ };
231
+
232
+ const HostStatusEnum = {
233
+ Up: 1,
234
+ Down: 2,
235
+ Timeouted: 3,
236
+ };
237
+
238
+ // By default, API Clients at Algolia have expiration delay
239
+ // of 5 mins. In the JavaScript client, we have 2 mins.
240
+ const EXPIRATION_DELAY = 2 * 60 * 1000;
241
+ function createStatefulHost(host, status = HostStatusEnum.Up) {
242
+ return {
243
+ ...host,
244
+ status,
245
+ lastUpdate: Date.now(),
246
+ };
247
+ }
248
+ function isStatefulHostUp(host) {
249
+ return host.status === HostStatusEnum.Up || Date.now() - host.lastUpdate > EXPIRATION_DELAY;
250
+ }
251
+ function isStatefulHostTimeouted(host) {
252
+ return (host.status === HostStatusEnum.Timeouted && Date.now() - host.lastUpdate <= EXPIRATION_DELAY);
253
+ }
254
+
255
+ function createStatelessHost(options) {
256
+ if (typeof options === 'string') {
257
+ return {
258
+ protocol: 'https',
259
+ url: options,
260
+ accept: CallEnum.Any,
261
+ };
262
+ }
263
+ return {
264
+ protocol: options.protocol || 'https',
265
+ url: options.url,
266
+ accept: options.accept || CallEnum.Any,
267
+ };
268
+ }
269
+
270
+ const MethodEnum = {
271
+ Delete: 'DELETE',
272
+ Get: 'GET',
273
+ Post: 'POST',
274
+ Put: 'PUT',
275
+ };
276
+
277
+ function createRetryableOptions(hostsCache, statelessHosts) {
278
+ return Promise.all(statelessHosts.map(statelessHost => {
279
+ return hostsCache.get(statelessHost, () => {
280
+ return Promise.resolve(createStatefulHost(statelessHost));
281
+ });
282
+ })).then(statefulHosts => {
283
+ const hostsUp = statefulHosts.filter(host => isStatefulHostUp(host));
284
+ const hostsTimeouted = statefulHosts.filter(host => isStatefulHostTimeouted(host));
285
+ /**
286
+ * Note, we put the hosts that previously timeouted on the end of the list.
287
+ */
288
+ const hostsAvailable = [...hostsUp, ...hostsTimeouted];
289
+ const statelessHostsAvailable = hostsAvailable.length > 0
290
+ ? hostsAvailable.map(host => createStatelessHost(host))
291
+ : statelessHosts;
292
+ return {
293
+ getTimeout(timeoutsCount, baseTimeout) {
294
+ /**
295
+ * Imagine that you have 4 hosts, if timeouts will increase
296
+ * on the following way: 1 (timeouted) > 4 (timeouted) > 5 (200)
297
+ *
298
+ * Note that, the very next request, we start from the previous timeout
299
+ *
300
+ * 5 (timeouted) > 6 (timeouted) > 7 ...
301
+ *
302
+ * This strategy may need to be reviewed, but is the strategy on the our
303
+ * current v3 version.
304
+ */
305
+ const timeoutMultiplier = hostsTimeouted.length === 0 && timeoutsCount === 0
306
+ ? 1
307
+ : hostsTimeouted.length + 3 + timeoutsCount;
308
+ return timeoutMultiplier * baseTimeout;
309
+ },
310
+ statelessHosts: statelessHostsAvailable,
311
+ };
312
+ });
313
+ }
314
+
315
+ const isNetworkError = ({ isTimedOut, status }) => {
316
+ return !isTimedOut && ~~status === 0;
317
+ };
318
+ const isRetryable = (response) => {
319
+ const status = response.status;
320
+ const isTimedOut = response.isTimedOut;
321
+ return (isTimedOut || isNetworkError(response) || (~~(status / 100) !== 2 && ~~(status / 100) !== 4));
322
+ };
323
+ const isSuccess = ({ status }) => {
324
+ return ~~(status / 100) === 2;
325
+ };
326
+ const retryDecision = (response, outcomes) => {
327
+ if (isRetryable(response)) {
328
+ return outcomes.onRetry(response);
329
+ }
330
+ if (isSuccess(response)) {
331
+ return outcomes.onSuccess(response);
332
+ }
333
+ return outcomes.onFail(response);
334
+ };
335
+
336
+ function retryableRequest(transporter, statelessHosts, request, requestOptions) {
337
+ const stackTrace = []; // eslint-disable-line functional/prefer-readonly-type
338
+ /**
339
+ * First we prepare the payload that do not depend from hosts.
340
+ */
341
+ const data = serializeData(request, requestOptions);
342
+ const headers = serializeHeaders(transporter, requestOptions);
343
+ const method = request.method;
344
+ // On `GET`, the data is proxied to query parameters.
345
+ const dataQueryParameters = request.method !== MethodEnum.Get
346
+ ? {}
347
+ : {
348
+ ...request.data,
349
+ ...requestOptions.data,
350
+ };
351
+ const queryParameters = {
352
+ 'x-algolia-agent': transporter.userAgent.value,
353
+ ...transporter.queryParameters,
354
+ ...dataQueryParameters,
355
+ ...requestOptions.queryParameters,
356
+ };
357
+ let timeoutsCount = 0; // eslint-disable-line functional/no-let
358
+ const retry = (hosts, // eslint-disable-line functional/prefer-readonly-type
359
+ getTimeout) => {
360
+ /**
361
+ * We iterate on each host, until there is no host left.
362
+ */
363
+ const host = hosts.pop(); // eslint-disable-line functional/immutable-data
364
+ if (host === undefined) {
365
+ throw createRetryError(stackTraceWithoutCredentials(stackTrace));
366
+ }
367
+ const payload = {
368
+ data,
369
+ headers,
370
+ method,
371
+ url: serializeUrl(host, request.path, queryParameters),
372
+ connectTimeout: getTimeout(timeoutsCount, transporter.timeouts.connect),
373
+ responseTimeout: getTimeout(timeoutsCount, requestOptions.timeout),
374
+ };
375
+ /**
376
+ * The stackFrame is pushed to the stackTrace so we
377
+ * can have information about onRetry and onFailure
378
+ * decisions.
379
+ */
380
+ const pushToStackTrace = (response) => {
381
+ const stackFrame = {
382
+ request: payload,
383
+ response,
384
+ host,
385
+ triesLeft: hosts.length,
386
+ };
387
+ // eslint-disable-next-line functional/immutable-data
388
+ stackTrace.push(stackFrame);
389
+ return stackFrame;
390
+ };
391
+ const decisions = {
392
+ onSuccess: response => deserializeSuccess(response),
393
+ onRetry(response) {
394
+ const stackFrame = pushToStackTrace(response);
395
+ /**
396
+ * If response is a timeout, we increaset the number of
397
+ * timeouts so we can increase the timeout later.
398
+ */
399
+ if (response.isTimedOut) {
400
+ timeoutsCount++;
401
+ }
402
+ return Promise.all([
403
+ /**
404
+ * Failures are individually send the logger, allowing
405
+ * the end user to debug / store stack frames even
406
+ * when a retry error does not happen.
407
+ */
408
+ transporter.logger.info('Retryable failure', stackFrameWithoutCredentials(stackFrame)),
409
+ /**
410
+ * We also store the state of the host in failure cases. If the host, is
411
+ * down it will remain down for the next 2 minutes. In a timeout situation,
412
+ * this host will be added end of the list of hosts on the next request.
413
+ */
414
+ transporter.hostsCache.set(host, createStatefulHost(host, response.isTimedOut ? HostStatusEnum.Timeouted : HostStatusEnum.Down)),
415
+ ]).then(() => retry(hosts, getTimeout));
416
+ },
417
+ onFail(response) {
418
+ pushToStackTrace(response);
419
+ throw deserializeFailure(response, stackTraceWithoutCredentials(stackTrace));
420
+ },
421
+ };
422
+ return transporter.requester.send(payload).then(response => {
423
+ return retryDecision(response, decisions);
424
+ });
425
+ };
426
+ /**
427
+ * Finally, for each retryable host perform request until we got a non
428
+ * retryable response. Some notes here:
429
+ *
430
+ * 1. The reverse here is applied so we can apply a `pop` later on => more performant.
431
+ * 2. We also get from the retryable options a timeout multiplier that is tailored
432
+ * for the current context.
433
+ */
434
+ return createRetryableOptions(transporter.hostsCache, statelessHosts).then(options => {
435
+ return retry([...options.statelessHosts].reverse(), options.getTimeout);
436
+ });
437
+ }
438
+
439
+ function createTransporter(options) {
440
+ const { hostsCache, logger, requester, requestsCache, responsesCache, timeouts, userAgent, hosts, queryParameters, headers, } = options;
441
+ const transporter = {
442
+ hostsCache,
443
+ logger,
444
+ requester,
445
+ requestsCache,
446
+ responsesCache,
447
+ timeouts,
448
+ userAgent,
449
+ headers,
450
+ queryParameters,
451
+ hosts: hosts.map(host => createStatelessHost(host)),
452
+ read(request, requestOptions) {
453
+ /**
454
+ * First, we compute the user request options. Now, keep in mind,
455
+ * that using request options the user is able to modified the intire
456
+ * payload of the request. Such as headers, query parameters, and others.
457
+ */
458
+ const mappedRequestOptions = createMappedRequestOptions(requestOptions, transporter.timeouts.read);
459
+ const createRetryableRequest = () => {
460
+ /**
461
+ * Then, we prepare a function factory that contains the construction of
462
+ * the retryable request. At this point, we may *not* perform the actual
463
+ * request. But we want to have the function factory ready.
464
+ */
465
+ return retryableRequest(transporter, transporter.hosts.filter(host => (host.accept & CallEnum.Read) !== 0), request, mappedRequestOptions);
466
+ };
467
+ /**
468
+ * Once we have the function factory ready, we need to determine of the
469
+ * request is "cacheable" - should be cached. Note that, once again,
470
+ * the user can force this option.
471
+ */
472
+ const cacheable = mappedRequestOptions.cacheable !== undefined
473
+ ? mappedRequestOptions.cacheable
474
+ : request.cacheable;
475
+ /**
476
+ * If is not "cacheable", we immediatly trigger the retryable request, no
477
+ * need to check cache implementations.
478
+ */
479
+ if (cacheable !== true) {
480
+ return createRetryableRequest();
481
+ }
482
+ /**
483
+ * If the request is "cacheable", we need to first compute the key to ask
484
+ * the cache implementations if this request is on progress or if the
485
+ * response already exists on the cache.
486
+ */
487
+ const key = {
488
+ request,
489
+ mappedRequestOptions,
490
+ transporter: {
491
+ queryParameters: transporter.queryParameters,
492
+ headers: transporter.headers,
493
+ },
494
+ };
495
+ /**
496
+ * With the computed key, we first ask the responses cache
497
+ * implemention if this request was been resolved before.
498
+ */
499
+ return transporter.responsesCache.get(key, () => {
500
+ /**
501
+ * If the request has never resolved before, we actually ask if there
502
+ * is a current request with the same key on progress.
503
+ */
504
+ return transporter.requestsCache.get(key, () => {
505
+ return (transporter.requestsCache
506
+ /**
507
+ * Finally, if there is no request in progress with the same key,
508
+ * this `createRetryableRequest()` will actually trigger the
509
+ * retryable request.
510
+ */
511
+ .set(key, createRetryableRequest())
512
+ .then(response => Promise.all([transporter.requestsCache.delete(key), response]), err => Promise.all([transporter.requestsCache.delete(key), Promise.reject(err)]))
513
+ .then(([_, response]) => response));
514
+ });
515
+ }, {
516
+ /**
517
+ * Of course, once we get this response back from the server, we
518
+ * tell response cache to actually store the received response
519
+ * to be used later.
520
+ */
521
+ miss: response => transporter.responsesCache.set(key, response),
522
+ });
523
+ },
524
+ write(request, requestOptions) {
525
+ /**
526
+ * On write requests, no cache mechanisms are applied, and we
527
+ * proxy the request immediately to the requester.
528
+ */
529
+ return retryableRequest(transporter, transporter.hosts.filter(host => (host.accept & CallEnum.Write) !== 0), request, createMappedRequestOptions(requestOptions, transporter.timeouts.write));
530
+ },
531
+ };
532
+ return transporter;
533
+ }
534
+
535
+ function createUserAgent(version) {
536
+ const userAgent = {
537
+ value: `Algolia for JavaScript (${version})`,
538
+ add(options) {
539
+ const addedUserAgent = `; ${options.segment}${options.version !== undefined ? ` (${options.version})` : ''}`;
540
+ if (userAgent.value.indexOf(addedUserAgent) === -1) {
541
+ // eslint-disable-next-line functional/immutable-data
542
+ userAgent.value = `${userAgent.value}${addedUserAgent}`;
543
+ }
544
+ return userAgent;
545
+ },
546
+ };
547
+ return userAgent;
548
+ }
549
+
550
+ function deserializeSuccess(response) {
551
+ // eslint-disable-next-line functional/no-try-statement
552
+ try {
553
+ return JSON.parse(response.content);
554
+ }
555
+ catch (e) {
556
+ throw createDeserializationError(e.message, response);
557
+ }
558
+ }
559
+ function deserializeFailure({ content, status }, stackFrame) {
560
+ // eslint-disable-next-line functional/no-let
561
+ let message = content;
562
+ // eslint-disable-next-line functional/no-try-statement
563
+ try {
564
+ message = JSON.parse(content).message;
565
+ }
566
+ catch (e) {
567
+ // ..
568
+ }
569
+ return createApiError(message, status, stackFrame);
570
+ }
571
+
572
+ function serializeUrl(host, path, queryParameters) {
573
+ const queryParametersAsString = serializeQueryParameters(queryParameters);
574
+ // eslint-disable-next-line functional/no-let
575
+ let url = `${host.protocol}://${host.url}/${path.charAt(0) === '/' ? path.substr(1) : path}`;
576
+ if (queryParametersAsString.length) {
577
+ url += `?${queryParametersAsString}`;
578
+ }
579
+ return url;
580
+ }
581
+ function serializeQueryParameters(parameters) {
582
+ const isObjectOrArray = (value) => Object.prototype.toString.call(value) === '[object Object]' ||
583
+ Object.prototype.toString.call(value) === '[object Array]';
584
+ return Object.keys(parameters)
585
+ .map(key => encode('%s=%s', key, isObjectOrArray(parameters[key]) ? JSON.stringify(parameters[key]) : parameters[key]))
586
+ .join('&');
587
+ }
588
+ function serializeData(request, requestOptions) {
589
+ if (request.method === MethodEnum.Get ||
590
+ (request.data === undefined && requestOptions.data === undefined)) {
591
+ return undefined;
592
+ }
593
+ const data = Array.isArray(request.data)
594
+ ? request.data
595
+ : { ...request.data, ...requestOptions.data };
596
+ return JSON.stringify(data);
597
+ }
598
+ function serializeHeaders(transporter, requestOptions) {
599
+ const headers = {
600
+ ...transporter.headers,
601
+ ...requestOptions.headers,
602
+ };
603
+ const serializedHeaders = {};
604
+ Object.keys(headers).forEach(header => {
605
+ const value = headers[header];
606
+ // @ts-ignore
607
+ // eslint-disable-next-line functional/immutable-data
608
+ serializedHeaders[header.toLowerCase()] = value;
609
+ });
610
+ return serializedHeaders;
611
+ }
612
+
613
+ function stackTraceWithoutCredentials(stackTrace) {
614
+ return stackTrace.map(stackFrame => stackFrameWithoutCredentials(stackFrame));
615
+ }
616
+ function stackFrameWithoutCredentials(stackFrame) {
617
+ const modifiedHeaders = stackFrame.request.headers['x-algolia-api-key']
618
+ ? { 'x-algolia-api-key': '*****' }
619
+ : {};
620
+ return {
621
+ ...stackFrame,
622
+ request: {
623
+ ...stackFrame.request,
624
+ headers: {
625
+ ...stackFrame.request.headers,
626
+ ...modifiedHeaders,
627
+ },
628
+ },
629
+ };
630
+ }
631
+
632
+ function createApiError(message, status, transporterStackTrace) {
633
+ return {
634
+ name: 'ApiError',
635
+ message,
636
+ status,
637
+ transporterStackTrace,
638
+ };
639
+ }
640
+
641
+ function createDeserializationError(message, response) {
642
+ return {
643
+ name: 'DeserializationError',
644
+ message,
645
+ response,
646
+ };
647
+ }
648
+
649
+ function createRetryError(transporterStackTrace) {
650
+ return {
651
+ name: 'RetryError',
652
+ message: 'Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.',
653
+ transporterStackTrace,
654
+ };
655
+ }
656
+
657
+ const createSearchClient = options => {
658
+ const appId = options.appId;
659
+ const auth = createAuth(options.authMode !== undefined ? options.authMode : AuthMode.WithinHeaders, appId, options.apiKey);
660
+ const transporter = createTransporter({
661
+ hosts: [
662
+ { url: `${appId}-dsn.algolia.net`, accept: CallEnum.Read },
663
+ { url: `${appId}.algolia.net`, accept: CallEnum.Write },
664
+ ].concat(shuffle([
665
+ { url: `${appId}-1.algolianet.com` },
666
+ { url: `${appId}-2.algolianet.com` },
667
+ { url: `${appId}-3.algolianet.com` },
668
+ ])),
669
+ ...options,
670
+ headers: {
671
+ ...auth.headers(),
672
+ ...{ 'content-type': 'application/x-www-form-urlencoded' },
673
+ ...options.headers,
674
+ },
675
+ queryParameters: {
676
+ ...auth.queryParameters(),
677
+ ...options.queryParameters,
678
+ },
679
+ });
680
+ const base = {
681
+ transporter,
682
+ appId,
683
+ addAlgoliaAgent(segment, version) {
684
+ transporter.userAgent.add({ segment, version });
685
+ },
686
+ clearCache() {
687
+ return Promise.all([
688
+ transporter.requestsCache.clear(),
689
+ transporter.responsesCache.clear(),
690
+ ]).then(() => undefined);
691
+ },
692
+ };
693
+ return addMethods(base, options.methods);
694
+ };
695
+
696
+ const customRequest = (base) => {
697
+ return (request, requestOptions) => {
698
+ if (request.method === MethodEnum.Get) {
699
+ return base.transporter.read(request, requestOptions);
700
+ }
701
+ return base.transporter.write(request, requestOptions);
702
+ };
703
+ };
704
+
705
+ const initIndex = (base) => {
706
+ return (indexName, options = {}) => {
707
+ const searchIndex = {
708
+ transporter: base.transporter,
709
+ appId: base.appId,
710
+ indexName,
711
+ };
712
+ return addMethods(searchIndex, options.methods);
713
+ };
714
+ };
715
+
716
+ const multipleQueries = (base) => {
717
+ return (queries, requestOptions) => {
718
+ const requests = queries.map(query => {
719
+ return {
720
+ ...query,
721
+ params: serializeQueryParameters(query.params || {}),
722
+ };
723
+ });
724
+ return base.transporter.read({
725
+ method: MethodEnum.Post,
726
+ path: '1/indexes/*/queries',
727
+ data: {
728
+ requests,
729
+ },
730
+ cacheable: true,
731
+ }, requestOptions);
732
+ };
733
+ };
734
+
735
+ const multipleSearchForFacetValues = (base) => {
736
+ return (queries, requestOptions) => {
737
+ return Promise.all(queries.map(query => {
738
+ const { facetName, facetQuery, ...params } = query.params;
739
+ return initIndex(base)(query.indexName, {
740
+ methods: { searchForFacetValues },
741
+ }).searchForFacetValues(facetName, facetQuery, {
742
+ ...requestOptions,
743
+ ...params,
744
+ });
745
+ }));
746
+ };
747
+ };
748
+
749
+ const findAnswers = (base) => {
750
+ return (query, queryLanguages, requestOptions) => {
751
+ return base.transporter.read({
752
+ method: MethodEnum.Post,
753
+ path: encode('1/answers/%s/prediction', base.indexName),
754
+ data: {
755
+ query,
756
+ queryLanguages,
757
+ },
758
+ cacheable: true,
759
+ }, requestOptions);
760
+ };
761
+ };
762
+
763
+ const search = (base) => {
764
+ return (query, requestOptions) => {
765
+ return base.transporter.read({
766
+ method: MethodEnum.Post,
767
+ path: encode('1/indexes/%s/query', base.indexName),
768
+ data: {
769
+ query,
770
+ },
771
+ cacheable: true,
772
+ }, requestOptions);
773
+ };
774
+ };
775
+
776
+ const searchForFacetValues = (base) => {
777
+ return (facetName, facetQuery, requestOptions) => {
778
+ return base.transporter.read({
779
+ method: MethodEnum.Post,
780
+ path: encode('1/indexes/%s/facets/%s/query', base.indexName, facetName),
781
+ data: {
782
+ facetQuery,
783
+ },
784
+ cacheable: true,
785
+ }, requestOptions);
786
+ };
787
+ };
788
+
789
+ const LogLevelEnum = {
790
+ Debug: 1,
791
+ Info: 2,
792
+ Error: 3,
793
+ };
794
+
795
+ /* eslint no-console: 0 */
796
+ function createConsoleLogger(logLevel) {
797
+ return {
798
+ debug(message, args) {
799
+ if (LogLevelEnum.Debug >= logLevel) {
800
+ console.debug(message, args);
801
+ }
802
+ return Promise.resolve();
803
+ },
804
+ info(message, args) {
805
+ if (LogLevelEnum.Info >= logLevel) {
806
+ console.info(message, args);
807
+ }
808
+ return Promise.resolve();
809
+ },
810
+ error(message, args) {
811
+ console.error(message, args);
812
+ return Promise.resolve();
813
+ },
814
+ };
815
+ }
816
+
817
+ function createBrowserXhrRequester() {
818
+ return {
819
+ send(request) {
820
+ return new Promise((resolve) => {
821
+ const baseRequester = new XMLHttpRequest();
822
+ baseRequester.open(request.method, request.url, true);
823
+ Object.keys(request.headers).forEach(key => baseRequester.setRequestHeader(key, request.headers[key]));
824
+ const createTimeout = (timeout, content) => {
825
+ return setTimeout(() => {
826
+ baseRequester.abort();
827
+ resolve({
828
+ status: 0,
829
+ content,
830
+ isTimedOut: true,
831
+ });
832
+ }, timeout * 1000);
833
+ };
834
+ const connectTimeout = createTimeout(request.connectTimeout, 'Connection timeout');
835
+ // eslint-disable-next-line functional/no-let
836
+ let responseTimeout;
837
+ // eslint-disable-next-line functional/immutable-data
838
+ baseRequester.onreadystatechange = () => {
839
+ if (baseRequester.readyState > baseRequester.OPENED && responseTimeout === undefined) {
840
+ clearTimeout(connectTimeout);
841
+ responseTimeout = createTimeout(request.responseTimeout, 'Socket timeout');
842
+ }
843
+ };
844
+ // eslint-disable-next-line functional/immutable-data
845
+ baseRequester.onerror = () => {
846
+ // istanbul ignore next
847
+ if (baseRequester.status === 0) {
848
+ clearTimeout(connectTimeout);
849
+ clearTimeout(responseTimeout);
850
+ resolve({
851
+ content: baseRequester.responseText || 'Network request failed',
852
+ status: baseRequester.status,
853
+ isTimedOut: false,
854
+ });
855
+ }
856
+ };
857
+ // eslint-disable-next-line functional/immutable-data
858
+ baseRequester.onload = () => {
859
+ clearTimeout(connectTimeout);
860
+ clearTimeout(responseTimeout);
861
+ resolve({
862
+ content: baseRequester.responseText,
863
+ status: baseRequester.status,
864
+ isTimedOut: false,
865
+ });
866
+ };
867
+ baseRequester.send(request.data);
868
+ });
869
+ },
870
+ };
871
+ }
872
+
873
+ function algoliasearch(appId, apiKey, options) {
874
+ const commonOptions = {
875
+ appId,
876
+ apiKey,
877
+ timeouts: {
878
+ connect: 1,
879
+ read: 2,
880
+ write: 30,
881
+ },
882
+ requester: createBrowserXhrRequester(),
883
+ logger: createConsoleLogger(LogLevelEnum.Error),
884
+ responsesCache: createInMemoryCache(),
885
+ requestsCache: createInMemoryCache({ serializable: false }),
886
+ hostsCache: createFallbackableCache({
887
+ caches: [
888
+ createBrowserLocalStorageCache({ key: `${version}-${appId}` }),
889
+ createInMemoryCache(),
890
+ ],
891
+ }),
892
+ userAgent: createUserAgent(version).add({
893
+ segment: 'Browser',
894
+ version: 'lite',
895
+ }),
896
+ authMode: AuthMode.WithinQueryParameters,
897
+ };
898
+ return createSearchClient({
899
+ ...commonOptions,
900
+ ...options,
901
+ methods: {
902
+ search: multipleQueries,
903
+ searchForFacetValues: multipleSearchForFacetValues,
904
+ multipleQueries,
905
+ multipleSearchForFacetValues,
906
+ customRequest,
907
+ initIndex: base => (indexName) => {
908
+ return initIndex(base)(indexName, {
909
+ methods: { search, searchForFacetValues, findAnswers },
910
+ });
911
+ },
912
+ },
913
+ });
914
+ }
915
+ // eslint-disable-next-line functional/immutable-data
916
+ algoliasearch.version = version;
917
+
918
+ export { algoliasearch as a };
919
+
920
+ //# sourceMappingURL=algoliasearch-lite.esm.browser.js.map